题意: 给你大堆的电话号码,现在如果一个电话号码是另一个电话号码的前缀的话,表示电话就会打不通,就要输出NO。否则就YES。
比如:911和91125425,因为911在91125425中出现了,所以不行。
思路:用最简单的字典树的代码,在录入的时候,做个小小的改动。
就是记录数字的个数的时候如果是最后最后一个的话,就是3,否则就是1;
比如:911,变成113
然后在将数字插入字典树的时候做个判断,如果这个数字遇到3的时候,表示前面出现过这个前缀。
或者一个数字的最后一个数字存放的字典树之前就有其他数字存放过,表示前面有个这个前缀的的数字。
#include<stdio.h> #include<string.h> int cur=1; int f; struct node { int next[11]; int idx; void init() { idx=0; memset(next,-1,sizeof(next)); } }; node t[5000110]; void insert(char *s) { int p=0; int n=strlen(s); for(int i=0;i<n;i++) { int x=s[i]-'0'; if(t[p].next[x]==-1) { t[cur].init(); t[p].next[x]=cur++; } p=t[p].next[x]; if(i==n-1) { if(t[p].idx==3||t[p].idx==1) f=1; } if(t[p].idx!=3) t[p].idx=1; else f=1; } t[p].idx=3; } int main() { int kj; scanf("%d",&kj); char s[200]; while(kj--) { t[0].init(); f=0; int n; scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%s",s);insert(s);} if(f) puts("NO"); else puts("YES"); } return 0; }