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 }
View Code

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 }
View Code

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 }
View Code

 

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 }
View Code

持续更新中...

 

posted @ 2014-08-15 16:16  Grubbyskyer  阅读(316)  评论(0编辑  收藏  举报