hdu 1247(Trie)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1247
思路:用字典树插入所有单词后直接枚举每个单词的每个分割点每个分割点的位置都入栈),然后再依此出栈判断此分割点分成的两个字符串是否都存在即可,如果所有的情况都不存在,返回false,否则,返回true;
View Code
1 #include<iostream> 2 using namespace std; 3 4 struct Tire{ 5 bool Is; 6 Tire *next[26]; 7 }; 8 Tire *root; 9 10 void CreateTire(char str[]){ 11 int len=strlen(str); 12 Tire *p=root,*q; 13 for(int i=0;i<len;i++){ 14 int id=str[i]-'a'; 15 if(p->next[id]==NULL){ 16 q=(Tire *)malloc(sizeof(Tire)); 17 q->Is=false; 18 for(int i=0;i<26;i++){ 19 q->next[i]=NULL; 20 } 21 p->next[id]=q; 22 p=p->next[id]; 23 }else { 24 p=p->next[id]; 25 } 26 } 27 p->Is=true;//单词结尾标记为true; 28 } 29 30 bool Search(char str[]){ 31 int i=0,top=0,stack[1010]; 32 int len=strlen(str); 33 Tire *p=root; 34 while(str[i]){ 35 int k=str[i++]-'a'; 36 if(p->next[k]==NULL)return false; 37 p=p->next[k]; 38 if(p->Is&&str[i]){ 39 stack[top++]=i;//找到该单词还有子单词的分割点,入栈 40 } 41 } 42 //从可能的分割点去找 43 while(top){ 44 bool tag=true; 45 i=stack[--top]; 46 p=root; 47 while(str[i]){ 48 int k=str[i++]-'a'; 49 if(p->next[k]==NULL){ 50 tag=false; 51 break; 52 } 53 p=p->next[k]; 54 } 55 //找到最后并且存在 56 if(tag&&p->Is){ 57 return true; 58 } 59 } 60 return false; 61 } 62 63 int main(){ 64 char str[50010][17]; 65 root=(Tire *)malloc(sizeof(Tire)); 66 for(int i=0;i<26;i++){ 67 root->next[i]=NULL; 68 } 69 root->Is=false; 70 int k=0; 71 while(~scanf("%s",str[k])){ 72 CreateTire(str[k++]); 73 } 74 for(int i=0;i<k;i++){ 75 if(Search(str[i])){ 76 printf("%s\n",str[i]); 77 } 78 } 79 return 0; 80 }