Phone List

OJ题号:UVa11362

思路:

Trie树。 前缀可分为两种情况,一种是当前结点是某个字符串的前缀,另一种是某个字符串是当前字符串的前缀。 每次插入时先判断新插入的结点是不是单词结点,如果是,就说明该字符串是当前字符串的前缀,直接跳出程序,输出NO。 一个单词插入完成后判断该单词结点下有没有子结点,如果有,就说明当前字符串是某个字符串的前缀,跳出程序,输出NO。 如果所有字符串插入完毕却没有跳出,就输出YES。 

 1 #define maxnode 100000
 2 #define sigma_size 10
 3 #include<cstdio>
 4 #include<cstring>
 5 bool ans;
 6 struct Trie {
 7     int ch[maxnode][sigma_size];
 8     int val[maxnode];
 9     int sz;
10     int idx(char c) {
11         return c-'0';
12     }
13     void insert(char *s) {
14         int u=0,n=strlen(s);
15         for(int i=0;i<n;i++) {
16             int c=idx(s[i]);
17             if(!ch[u][c]) {
18                 memset(ch[sz],0,sizeof(ch[sz]));
19                 val[sz]=0;//visited
20                 ch[u][c]=sz++;
21             }
22             if(val[u]==1) {
23                 ans=true;
24                 return;
25             }
26             u=ch[u][c];
27         }
28         /*if(val[u]==0) {
29             ans=true;
30             return;
31         }*/
32         val[u]=1;
33         for(int i=0;i<sigma_size;i++) {
34             if(ch[u][i]) {
35                 ans=true;
36                 return;
37             }
38         }
39     }
40 };
41 Trie trie;
42 int main() {
43     int t;
44     scanf("%d",&t);
45     while(t--) {
46         int n;
47         scanf("%d",&n);
48         ans=false;
49         memset(&trie,0,sizeof(trie));
50         trie.sz=1;
51         memset(trie.ch[0],0,sizeof(trie.ch[0]));
52         while(n--) {
53             char s[10];
54             scanf("%s",s);
55             trie.insert(s);
56         }
57         printf(ans?"NO\n":"YES\n");
58     }
59     return 0;
60 } 

注:本随笔整理自QQ空间旧文。发布时间为2017年3月14日。

查看原文

posted @ 2017-05-06 15:49  skylee03  阅读(130)  评论(0编辑  收藏  举报