这么多年过去了, 最开始接触的时候是大二,那个时候觉得思想蛮好懂的,就是实现起来困难。
事隔这么多年,一晃4年都快过去了,重新写了一遍,觉得蛮有感触,老狗,加油!
banana band bee absolute acm ba b band abc
2 3 1 0
const int Max_N = 26 ; struct TrieNode{ int EndSize ; TrieNode *next[Max_N] ; }; void insert_string(TrieNode *root , char *s){ if(root == NULL || *s == '\0') return ; TrieNode *now = root ; while(*s != '\0'){ if(now->next[*s - 'a'] == NULL){ TrieNode *node = (TrieNode *)malloc(sizeof(TrieNode)) ; for(int i = 0 ; i < Max_N ; i++) node->next[i] = NULL ; node->EndSize = 1 ; now->next[*s - 'a'] = node ; now = node ; } else{ now = now->next[*s - 'a'] ; now->EndSize++ ; } s++ ; } } int search_string(TrieNode *root , char *s){ if(root == NULL || *s == '\0') return 0 ; TrieNode *now = root ; while(now != NULL && *s != '\0'){ now = now->next[*s - 'a'] ; s++ ; } if(now == NULL) return 0 ; else return now->EndSize ; } void clear_trie(TrieNode *root){ for(int i = 0 ; i < Max_N ; i++){ if(root->next[i] != NULL) clear_trie(root->next[i]) ; } free(root) ; } int main(){ char str[100] ; TrieNode *root = (TrieNode *)malloc(sizeof(TrieNode)) ; for(int i = 0 ; i < Max_N ; i++) root->next[i] = NULL ; while(gets(str)){ if(*str == '\0') break ; insert_string(root , str) ; } while(gets(str)){ printf("%d\n" ,search_string(root , str)) ; } clear_trie(root) ; return 0 ; }
http://acm.hdu.edu.cn/showproblem.php?pid=1671
const int Max_N = 10 ; struct TrieNode{ int isEndstr ; TrieNode *next[Max_N] ; TrieNode(){ for(int i = 0 ; i < Max_N ; i++) this->next[i] = NULL ; isEndstr = 0 ; } }; int insert_string(TrieNode *root , char *s){ TrieNode *now = root ; while(*(s+1) != '\0'){ if(now->next[*s - '0'] == NULL){ TrieNode *node = new TrieNode() ; now->next[*s - '0'] = node ; now = node ; } else{ now = now->next[*s - '0'] ; if(now->isEndstr) //此处有单词结束 return 0 ; } s++ ; } if(now->next[*s - '0'] == NULL){ TrieNode *node = new TrieNode() ; now->next[*s - '0'] = node ; now = node ; } else //结束单词之前出现过。 return 0 ; now->isEndstr = 1 ; return 1 ; } void clear_trie(TrieNode *root){ for(int i = 0 ; i < Max_N ; i++){ if(root->next[i] != NULL) clear_trie(root->next[i]) ; } free(root) ; } char word[10008][11]; int N ; int Ans(TrieNode *root){ int i ; for(i = 1 ; i <= N ; i++){ if(! insert_string(root , word[i])) return 0 ; } return 1 ; } int main(){ int T ,i ; cin>>T ; while(T--){ scanf("%d" ,&N) ; for(i = 1 ; i <= N ; i++) scanf("%s" , word[i]) ; TrieNode *root = new TrieNode() ; if(Ans(root)) puts("YES") ; else puts("NO") ; clear_trie(root) ; } return 0 ; }
动物统计加强版
10 boar pig sheep gazelle sheep sheep alpaca alpaca marmot mole
sheep 3
在节点中加入一个父亲节点指针,这样输出串的时候就可以找到父亲节点。
const int Max_N = 26 ; struct TrieNode{ int EndSize ; char ch ; TrieNode *next[Max_N] ; TrieNode *father ; TrieNode(){} TrieNode(char c){ EndSize = 0 ; for(int i = 0 ; i < Max_N ; i++) this->next[i] = NULL ; ch = c ; } }; TrieNode *EndNode ; int Max_string ; void insert_string(TrieNode *root , char *s){ if(root == NULL || *s == '\0') return ; TrieNode *now = root ; while(*(s+1) != '\0'){ if(now->next[*s - 'a'] == NULL){ TrieNode *node = new TrieNode(*s) ; node->father = now ; now->next[*s - 'a'] = node ; now = node ; } else now = now->next[*s - 'a'] ; s++ ; } if(now->next[*s - 'a'] == NULL){ TrieNode *node = new TrieNode(*s) ; node->father = now ; now->next[*s - 'a'] = node ; now = node ; } else now = now->next[*s - 'a'] ; now->EndSize++ ; if(Max_string < now->EndSize){ EndNode = now ; Max_string = now->EndSize ; } } void clear_trie(TrieNode *root){ for(int i = 0 ; i < Max_N ; i++){ if(root->next[i] != NULL) clear_trie(root->next[i]) ; } free(root) ; } void Ans(TrieNode *root){ vector<int>ans ; ans.clear() ; TrieNode *now = EndNode ; while(now->father != root){ ans.push_back(now->ch) ; now = now->father ; } ans.push_back(now->ch) ; for(int i = ans.size() -1 ; i >= 0 ; i--) putchar(ans[i]) ; return ; } int main(){ int n ; char str[12] ; while(scanf("%d" ,&n) != EOF){ TrieNode *root = new TrieNode('*') ; Max_string = 0 ; while(n--){ scanf("%s" ,str) ; insert_string(root , str) ; } Ans(root) ; printf(" %d\n" , Max_string) ; clear_trie(root) ; } return 0 ; }
Xor Sum
Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包含一个正整数 S ,之后 Zeus 需要在集合当中找出一个正整数 K ,使得 K 与 S 的异或结果最大。Prometheus 为了让 Zeus 看到人类的伟大,随即同意 Zeus 可以向人类求助。你能证明人类的智慧么?
Input
输入包含若干组测试数据,每组测试数据包含若干行。
输入的第一行是一个整数T(T < 10),表示共有T组数据。
每组数据的第一行输入两个正整数N,M(<1=N,M<=100000),接下来一行,包含N个正整数,代表 Zeus 的获得的集合,之后M行,每行一个正整数S,代表 Prometheus 询问的正整数。所有正整数均不超过2^32。
Output
对于每组数据,首先需要输出单独一行”Case #?:”,其中问号处应填入当前的数据组数,组数从1开始计算。
对于每个询问,输出一个正整数K,使得K与S异或值最大。
Sample Input
2
3 2
3 4 5
1
5
4 1
4 6 5 6
3
Sample Output
Case #1:
4
3
Case #2:
4
Source
2014年百度之星程序设计大赛 - 资格赛
struct TrieNode{ int val ; TrieNode *next[2] ; }; void Insert(TrieNode * root , int x){ int t ; TrieNode *now = root ; for(int i = 31 ; i >= 0 ; i--){ if(x & (1<<i)) t = 1 ; else t = 0 ; if(now->next[t] == NULL){ TrieNode *node = (TrieNode *)malloc(sizeof(TrieNode)) ; node->next[0] = node->next[1] = NULL ; now->next[t] = node ; now = node ; } else now = now->next[t] ; } now->val = x ; } int Get(TrieNode *root , int x){ int t ; TrieNode *now = root ; for(int i = 31 ; i >= 0 ; i--){ if(x & (1<<i)) t = 1 ; else t = 0 ; if(now->next[t^1] != NULL) now = now->next[t^1] ; else now = now->next[t] ; } return now->val ; } void Clear(TrieNode *root){ for(int i = 0 ; i <= 1 ; i++){ if(root->next[i] != NULL) Clear(root->next[i]) ; } free(root) ; } int main(){ int t , n , m , T = 1 , x ; cin>>t ; while(t--){ TrieNode *root = (TrieNode *)malloc(sizeof(TrieNode)) ; root->next[0] = root->next[1] = NULL ; scanf("%d%d" ,&n,&m) ; while(n--){ scanf("%d" ,&x) ; Insert(root , x) ; } printf("Case #%d:\n" , T++) ; while(m--){ scanf("%d" ,&x) ; printf("%d\n" ,Get(root , x)) ; } } return 0 ; }