Trie
写过一篇字典树的详解+模版
http://www.cnblogs.com/grubbyskyer/p/3843243.html
ZOJ 1109 Language of Fatmouse
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=109
用map完全能水过,不过还是练一下手...
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<iostream> 5 #define MAXN 26 6 using namespace std; 7 typedef struct Trie 8 { 9 Trie *next[MAXN]; 10 char word[10]; 11 }Trie; 12 13 Trie root; 14 15 void createTrie(char *str, char* str1) 16 { 17 Trie *p = &root, *q; 18 for (int i = 0; i < strlen(str); ++i) 19 { 20 int id = str[i] - 'a'; 21 if (p->next[id] == NULL) 22 { 23 q = (Trie*)malloc(sizeof(Trie)); 24 25 for (int i = 0; i < MAXN; ++i) 26 { 27 q->next[i] = NULL; 28 } 29 p->next[id] = q; 30 p = p->next[id]; 31 }else 32 { 33 p = p->next[id]; 34 } 35 } 36 strcpy(p->word, str1); 37 } 38 39 string findTrie(char *str) 40 { 41 Trie *p = &root; 42 43 for (int i = 0; i < strlen(str); ++i) 44 { 45 int id = str[i] - 'a'; 46 if (p->next[id] == NULL) 47 { 48 string s = "eh"; 49 50 return s; 51 }else 52 { 53 p = p->next[id]; 54 } 55 } 56 57 return p->word; 58 } 59 60 int main() 61 { 62 char line[25]; 63 // string word; 64 char word[10]; 65 char dic[10]; 66 int a = 0; 67 char op; 68 string ans; 69 while(1) 70 { 71 op = cin.peek(); 72 if(op == '\n') 73 { 74 cin.get(); 75 op = cin.peek(); 76 if(op == '\n') 77 { 78 cin.get(); 79 break; 80 } 81 } 82 scanf("%s", &word);; 83 scanf("%s", &dic); 84 // word = hah; 85 createTrie(dic, word); 86 } 87 while(scanf("%s", dic) != EOF) 88 { 89 ans = findTrie(dic); 90 cout << ans <<endl; 91 } 92 return 0; 93 }
COJ 1216 异或最大值
http://122.207.68.93/OnlineJudge/problem.php?id=1216
COJ 1323 ZZY and his little friends
http://122.207.68.93/OnlineJudge/problem.php?id=1323
这两道题都是在n个数中求任两个数异或的最大值,考虑将每个数字的二进制01串建成Trie,
和它异或最大的必是按照贪心原则每次选择和它不一样的串得到的数(如果存在的话 0选1 1选0)
最后遍历一边数组对每个数都求一个异或的最大值,其中最大的就是答案,具体见代码吧...
1 #include<cstdio> 2 #include<cstdlib> 3 #define MAXN 100005 4 int a[MAXN]; 5 int str[31]; 6 typedef struct Trie 7 { 8 Trie *next[2]; 9 int v; 10 }Trie; 11 Trie *root; 12 void createTrie(int x) 13 { 14 int k=1; 15 for(int i=30;i>=0;i--)//得到01串 16 { 17 if((k<<i)&x) 18 { 19 str[30-i]=1; 20 }else 21 { 22 str[30-i]=0; 23 } 24 } 25 Trie *p=root,*q; 26 for(int i=0;i<31;i++) 27 { 28 int id=str[i]; 29 if(p->next[id]==NULL) 30 { 31 q=(Trie*)malloc(sizeof(Trie)); 32 for(int j=0;j<2;j++) 33 { 34 q->next[j]=NULL; 35 } 36 q->v=0; 37 p->next[id]=q; 38 } 39 p=p->next[id]; 40 } 41 p->v=x;//在最后的结点里保存上这个数的十进制值,便于等下查找时候取异或 42 } 43 int findMax(int x) 44 { 45 int k=1; 46 for(int i=30;i>=0;i--) 47 { 48 if((k<<i)&x) 49 { 50 str[30-i]=1; 51 }else 52 { 53 str[30-i]=0; 54 } 55 } 56 Trie *p=root; 57 for(int i=0;i<31;i++) 58 { 59 int id=str[i]; 60 if(p->next[(id+1)%2]!=NULL)//贪心的往下选 0选1 1选0 61 { 62 p=p->next[(id+1)%2]; 63 }else//不存在的话没办法了 0还是0 1还是1 64 { 65 p=p->next[id]; 66 } 67 } 68 return x^(p->v);//返回x与此数的异或值 这个数就是整个数组中与x异或最大的那个 69 } 70 int delTrie(Trie *T) 71 { 72 if(T==NULL) 73 { 74 return 0; 75 }else 76 { 77 for(int i=0;i<2;i++) 78 { 79 if(T->next[i]!=NULL) 80 { 81 delTrie(T->next[i]); 82 } 83 } 84 } 85 free(T); 86 return 0; 87 } 88 int main() 89 { 90 int n; 91 while(~scanf("%d",&n)) 92 { 93 int max=0; 94 root=(Trie*)malloc(sizeof(Trie)); 95 for(int i = 0; i < 2; i++) 96 { 97 root->next[i] = NULL; 98 } 99 for(int i=0;i<n;i++) 100 { 101 scanf("%d", &a[i]); 102 createTrie(a[i]); 103 } 104 for(int i=0;i<n;i++) 105 { 106 if(findMax(a[i])>max) 107 { 108 max=findMax(a[i]); 109 } 110 } 111 printf("%d\n",max); 112 delTrie(root); 113 } 114 return 0; 115 }
1323的这份写的更清晰一点
1 #include<cstdio> 2 #include<cstdlib> 3 #define REP(i,a,b) for(int i = a; i < b; i++) 4 int n,m,flag,a[100005]; 5 int str[32]; 6 struct Trie 7 { 8 Trie *next[2]; 9 int v; 10 }; 11 Trie *root; 12 int init(int n) 13 { 14 int k = 1; 15 REP(i,0,31) { 16 if((k<<i)&n) str[30-i]=1; 17 else str[30-i]=0; 18 } 19 return 0; 20 } 21 void create(int n) 22 { 23 init(n); 24 Trie *p = root, *q; 25 REP(i,0,31) { 26 int id = str[i]; 27 if(p->next[id]==NULL) 28 { 29 q=(Trie*)malloc(sizeof(Trie)); 30 REP(j,0,2) { 31 q->next[j]=NULL; 32 } 33 q->v=0; 34 p->next[id]=q; 35 } 36 p=p->next[id]; 37 } 38 p->v=n; 39 } 40 int find(int n) 41 { 42 init(n); 43 Trie *p = root; 44 REP(i,0,31) { 45 int id = str[i]; 46 if(p->next[(id+1)%2]!=NULL) p=p->next[(id+1)%2]; 47 else p=p->next[id]; 48 } 49 return (p->v)^n; 50 } 51 int del(Trie *p) 52 { 53 if(p==NULL) return 0; 54 REP(i,0,2) { 55 if(p->next[i]!=NULL) del(p->next[i]); 56 } 57 free(p); 58 return 0; 59 } 60 int main() 61 { 62 while(scanf("%d%d",&n,&m)!=EOF) 63 { 64 flag=0; 65 root=(Trie*)malloc(sizeof(Trie)); 66 REP(i,0,2) { 67 root->next[i]=NULL; 68 } 69 REP(i,0,n) { 70 scanf("%d",&a[i]); 71 create(a[i]); 72 } 73 REP(i,0,n) { 74 if(find(a[i])>m) 75 { 76 flag=1; 77 break; 78 } 79 } 80 flag?puts("YES"):puts("NO"); 81 del(root); 82 } 83 return 0; 84 }
COJ 1115 最短的名字
http://122.207.68.93/OnlineJudge/problem.php?id=1115
第八届湖南省赛的题目 有很多种解法 我是用字典树做的
对整个村所有的名字建树 建树过程中根据v来标记已经存在的和不存在的结点
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdlib> 5 #include<vector> 6 #define MAXN 26 7 8 using namespace std; 9 10 typedef struct Trie 11 { 12 Trie *next[MAXN]; 13 int v; 14 }Trie; 15 Trie *root; 16 void createTrie(string s) 17 { 18 int n = s.length(); 19 char str[n]; 20 strcpy(str, s.c_str()); 21 Trie *p = root, *q; 22 for (int i = 0; i < strlen(str); ++i) 23 { 24 int id = str[i] - 'a'; 25 if (p->next[id] == NULL) 26 { 27 q = (Trie*)malloc(sizeof(Trie)); 28 q->v = 1; 29 for (int j = 0; j < MAXN; ++j) 30 { 31 q->next[j] = NULL; 32 } 33 p->next[id] = q; 34 p = p->next[id]; 35 }else 36 { 37 p->next[id]->v++; 38 p = p->next[id]; 39 } 40 } 41 } 42 int findTrie(string s) 43 { 44 int n = s.length(); 45 char str[n]; 46 strcpy(str, s.c_str()); 47 Trie *p = root; 48 for (int i = 0; i < strlen(str); ++i) 49 { 50 int id = str[i] - 'a'; 51 if (p->next[id]->v == 1) 52 { 53 return i+1; 54 }else 55 { 56 p = p->next[id]; 57 } 58 } 59 return strlen(str); 60 } 61 void deleteTrie(Trie *T) 62 { 63 for (int i = 0; i < MAXN; ++i) 64 { 65 if (T->next[i] != NULL) 66 { 67 deleteTrie(T->next[i]); 68 } 69 } 70 free(T); 71 } 72 int main() 73 { 74 int T, n; 75 scanf("%d", &T); 76 while(T--) 77 { 78 vector<string> strArray; 79 int ans = 0; 80 root = (Trie*)malloc(sizeof(Trie)); 81 for (int i = 0; i < MAXN; ++i) 82 { 83 root->next[i] = NULL; 84 } 85 scanf("%d", &n); 86 string s; 87 for (int i = 0; i < n; ++i) 88 { 89 cin >> s; 90 createTrie(s); 91 strArray.push_back(s); 92 } 93 for (int i = 0; i < strArray.size(); i++) 94 { 95 ans += findTrie(strArray[i]); 96 } 97 printf("%d\n", ans); 98 deleteTrie(root); 99 } 100 return 0; 101 }
持续更新中...