HDU 1247 Hat’s Words(字典树)
题目大意
字典中,一个单词是一个 hat's word:这个单词可以由字典中另外两个单词拼接而成
给你一个字典,求出字典中所有的 hat's word
单词最多有 50000 个
做法分析
看到这道题,感觉无从下手,单词的数量这么多,但是仔细一想,单词数是多了,但是如果每个单词的平均长度必然就小了,不然光是读入数据就得超时
于是,先乱搞一发再说
建立一棵字典树,然后,对于每个单词,直接暴力,竟然神奇的过了!
暴力的做法是:枚举第一个子单词的长度,剩下的为第二个子单词,分别在字典树中匹配,看能否找到一个单词与两个单词匹配,能的话,这是一个 hat's word
参考代码
HDU 1247
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 6 using namespace std; 7 8 struct Tire 9 { 10 struct Node 11 { 12 Node *next[26]; 13 bool flag; 14 Node() 15 { 16 for(int i=0; i<26; i++) next[i]=NULL; 17 flag=0; 18 } 19 }; 20 Node *root; 21 Tire() 22 { 23 root=new Node(); 24 } 25 26 void Insert(char s[]) 27 { 28 Node *u=root; 29 for(int i=0; s[i]; i++) 30 { 31 int v=s[i]-'a'; 32 if(u->next[v]==NULL) u->next[v]=new Node(); 33 u=u->next[v]; 34 } 35 u->flag=1; 36 } 37 38 bool Find(char buff[], int s, int t) 39 { 40 Node *u=root; 41 for(int i=s; i<=t; i++) 42 { 43 int v=buff[i]-'a'; 44 if(u->next[v]==NULL) return false; 45 u=u->next[v]; 46 } 47 return u->flag; 48 } 49 } tree; 50 51 char s[50005][100]; 52 int tot; 53 54 int main() 55 { 56 for(tot=0; scanf("%s", s[tot])!=EOF; tot++) 57 tree.Insert(s[tot]); 58 for(int i=0; i<tot; i++) 59 { 60 int t=(int)strlen(s[i])-1; 61 for(int j=0; j<t; j++) 62 if(tree.Find(s[i], 0, j) && tree.Find(s[i], j+1, t)) 63 { 64 printf("%s\n", s[i]); 65 break; 66 } 67 } 68 return 0; 69 }
AC通道