几道字典树基础题
转载请注明出处,谢谢。http://www.cnblogs.com/acmer-roney/---by Roney
What Are You Talking About HDU 1075
题意:给你一些火星文单词和对应的英文单词,再给你一些火星文让你翻译成英文。
题解:字典树的简单应用。插入单词时,在单词的根位置记录下对应的英文,再用一个标记变量标记一下,方便查找。
AC代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 using namespace std; 6 const int kind=26; 7 struct Trie{ 8 char *s; 9 bool mark; 10 Trie *Next[kind]; 11 }Memory[10000000]; 12 int allcop=0; 13 int all=0; 14 Trie *Root=NULL; 15 char mar[11],eng[11],mars[3005],c; 16 Trie *CreateTrieNode(){ 17 Trie *p=&Memory[allcop++]; 18 p->mark=false; 19 for(int i=0;i<kind;i++) 20 p->Next[i]=NULL; 21 return p; 22 } 23 bool search(char *s){ 24 Trie *p=Root; 25 int i=0,branch; 26 while(s[i]){ 27 branch=s[i++]-'a'; 28 if(!p->Next[branch])return false; 29 p=p->Next[branch]; 30 } 31 if(p->mark){ 32 printf("%s",p->s); 33 return true; 34 } 35 return false; 36 } 37 void insert(char *s,char*trans){ 38 Trie *pRoot=Root; 39 if(pRoot==NULL)pRoot=Root=CreateTrieNode(); 40 int i=0,branch; 41 while(s[i]){ 42 branch=s[i++]-'a'; 43 if(!pRoot->Next[branch])pRoot->Next[branch]=CreateTrieNode(); 44 pRoot=pRoot->Next[branch]; 45 } 46 pRoot->s=trans; 47 pRoot->mark=true; 48 } 49 int main() 50 { 51 //freopen("in.txt","r",stdin); 52 scanf("%s",eng); 53 while(scanf("%s",eng),strcmp(eng,"END")){ 54 char *trans=(char*)malloc(sizeof(eng)); 55 strcpy(trans,eng); 56 scanf("%s",mar); 57 insert(mar,trans); 58 } 59 scanf("%s",eng);getchar(); 60 while(c=getchar()){ 61 if((c<'a'||c>'z')&&(c<'A'||c>'Z')){ 62 mars[all]='\0'; 63 if(!strcmp(mars,"END"))break; 64 if(!search(mars))printf("%s",mars); 65 printf("%c",c); 66 all=0; 67 } 68 else mars[all++]=c; 69 } 70 return 0; 71 }
Let the Balloon Rise HDU 1004
题意:给你一些气球的颜色,让你统计并输出气球颜色最多的一种。
题解:字典树,只要在插入单词时记录一下每个单词出现的次数即可。
AC代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<string> 5 using namespace std; 6 const int N=20; 7 const int kind=26; 8 struct TrieNode{ 9 int count; 10 TrieNode *next[kind]; 11 }Memory[10000000]; 12 TrieNode *Root; 13 char s[N],ans[N]; 14 int n,allcop,num; 15 TrieNode *CreateTrieNode(){ 16 TrieNode *p=&Memory[allcop++]; 17 p->count=0; 18 for(int i=0;i<kind;i++) 19 p->next[i]=NULL; 20 return p; 21 } 22 void Insert(char *s){ 23 TrieNode *p=Root; 24 if(!p)p=Root=CreateTrieNode(); 25 int i=0,branch; 26 while(s[i]){ 27 branch=s[i++]-'a'; 28 if(!p->next[branch])p->next[branch]=CreateTrieNode(); 29 p=p->next[branch]; 30 } 31 p->count++; 32 if(p->count>num){ 33 num=p->count; 34 strcpy(ans,s); 35 } 36 } 37 int main() 38 { 39 //freopen("in.txt","r",stdin); 40 while(scanf("%d",&n),n){ 41 Root=NULL;allcop=num=0; 42 for(int i=0;i<n;i++){ 43 cin>>s; 44 Insert(s); 45 } 46 printf("%s\n",ans); 47 } 48 return 0; 49 }
此题亦可用C++ STL中的map来做,而且就此题而言效率更高。这里同样给出代码:
AC代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<iostream> 3 #include<map> 4 #include<cstring> 5 #include<string> 6 using namespace std; 7 const int N=20; 8 char s[N],ans[N]; 9 int n,num; 10 int main() 11 { 12 //freopen("in.txt","r",stdin); 13 map<string,int>mp; 14 while(scanf("%d",&n),n){ 15 num=0; 16 for(int i=0;i<n;i++){ 17 cin>>s; 18 ++mp[s]; 19 if(mp[s]>num){ 20 num=mp[s]; 21 strcpy(ans,s); 22 } 23 } 24 printf("%s\n",ans); 25 mp.clear(); 26 } 27 return 0; 28 }
统计难题 HDU 1251
题意:给你一些单词,再给你一些前缀,让你统计出该前缀在这些单词中出现的次数。
题解:字典树。插入单词时记录下每个单词的所有前缀一共出现的次数。
AC代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<stdio.h> 2 #define MAX 26 3 int allcop=0; 4 typedef struct TrieNode{ 5 int ncount; 6 struct TrieNode *Next[MAX]; 7 }TrieNode; 8 TrieNode Memory[10000000]; 9 void InitRoot(TrieNode * * pRoot){ 10 pRoot=NULL; 11 } 12 TrieNode *CreatTrieNode(){ 13 int i; 14 TrieNode *p; 15 p=&Memory[allcop++]; 16 p->ncount=1; 17 for(i=0;i<MAX;i++) 18 p->Next[i]=NULL; 19 return p; 20 } 21 void InsertTrie(TrieNode **pRoot,char *s){ 22 int i=0,k; 23 TrieNode *p; 24 if(!(p=*pRoot))p=*pRoot=CreatTrieNode(); 25 while(s[i]){ 26 k=s[i++]-'a'; 27 if(p->Next[k])p->Next[k]->ncount++; 28 else p->Next[k]=CreatTrieNode(); 29 p=p->Next[k]; 30 } 31 } 32 int searchTrie(TrieNode **pRoot,char *s){ 33 TrieNode *p; 34 int i=0,k; 35 if(!(p=*pRoot))return 0; 36 while(s[i]){ 37 k=s[i++]-'a'; 38 if(p->Next[k])p=p->Next[k]; 39 else return 0; 40 } 41 return p->ncount; 42 } 43 int main() 44 { 45 char s[11]; 46 TrieNode **Root=NULL; 47 InitRoot(&Root); 48 while(gets(s),s[0]) 49 InsertTrie(&Root,s); 50 while(gets(s)) 51 printf("%d\n",searchTrie(&Root,s)); 52 return 0; 53 }
还有一些字典树的入门题,在此不给出代码了。以下给出这些题的列表:
Flying to the Mars HDU 1800
Phone List HDU 1671
Hat’s Words HDU 1247
posted on 2012-09-14 20:46 Acmer_Roney 阅读(337) 评论(0) 编辑 收藏 举报