http://acm.hdu.edu.cn/showproblem.php?pid=1251
统计难题
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131070/65535 K (Java/Others)
Total Submission(s): 21236 Accepted Submission(s): 9145
Problem Description
Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).
Input
输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串.
注意:本题只有一组测试数据,处理到文件结束.
注意:本题只有一组测试数据,处理到文件结束.
Output
对于每个提问,给出以该字符串为前缀的单词的数量.
Sample Input
banana
band
bee
absolute
acm
ba
b
band
abc
Sample Output
2
3
1
0
分析:
字典树。
AC代码:
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 #include<queue> 6 #include<string> 7 #include<cmath> 8 using namespace std; 9 char ss[1010][1010]; 10 #define MAX 27 11 struct trie 12 { 13 trie *next[MAX]; 14 int v; 15 trie() 16 { 17 int i; 18 v=0; 19 for(i=0; i<26; i++) next[i]=NULL; 20 } 21 }; 22 trie *p,*q; 23 void creattrie(char *str,trie *root) 24 { 25 int len = strlen(str); 26 p = root; 27 for(int i=0;i<len; i++) 28 { 29 int id = str[i] - 'a'; 30 if(p->next[id] == NULL) 31 { 32 q=new trie; 33 q->v = 1; 34 p->next[id] = q; 35 p=q; 36 } 37 else 38 { 39 p=p->next[id]; 40 p->v+=1; 41 } 42 } 43 } 44 int findtrie(char *str,trie *root) 45 { 46 int i; 47 int len = strlen(str); 48 p = root; 49 for(i=0;i<len;i++) 50 { 51 int id = str[i] - 'a'; 52 p=p->next[id]; 53 if(p->v == 1) 54 { 55 return i+1; 56 } 57 } 58 } 59 int main() 60 { 61 int T,n,ans; 62 scanf("%d",&T); 63 while(T--) 64 { 65 ans = 0; 66 trie *root = new trie; 67 scanf("%d",&n); 68 //getchar(); 69 for(int i=0;i<n;i++) 70 { 71 scanf("%s", ss[i]);//用gets接收会有WA 72 creattrie(ss[i],root); 73 } 74 for(int i=0;i<n;i++) 75 { 76 int kk = findtrie(ss[i],root); 77 ans = ans+kk; 78 } 79 printf("%d ",ans); 80 } 81 return 0; 82 }