Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131070/65535 K (Java/Others)
Total Submission(s): 14730 Accepted Submission(s): 6347
Problem Description
Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).
Input
输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串.
注意:本题只有一组测试数据,处理到文件结束.
Output
对于每个提问,给出以该字符串为前缀的单词的数量.
Sample Input
banana
band
bee
absolute
acm
ba
b
band
abc
Sample Output
2
3
1
0
分析:字典树模版的变形,即用tree[tree[s].next[m]].w来记录单词字母出现的次数。
程序:
#include"string.h" #include"stdio.h" #define M 100001 struct st { int next[28]; int w; }tree[M*4]; int index; void creat(int k,char *ch) { int len=strlen(ch); int i,s=0; for(i=1;i<=len;i++) { int m=ch[i-1]-'a'+1; if(tree[s].next[m]==0) { tree[index].w++;//注意此处的变化 tree[s].next[m]=index++; } else tree[tree[s].next[m]].w++; s=tree[s].next[m]; } } int finde(char *ch) { int len=strlen(ch); int i,s=0; for(i=1;i<=len;i++) { int m=ch[i-1]-'a'+1; if(tree[s].next[m]!=0) { if(i==len&&tree[tree[s].next[m]].w!=0) return tree[tree[s].next[m]].w; s=tree[s].next[m]; } else return 0; } return 0; } int main() { char ch[33]; int k=1; memset(tree,0,sizeof(tree)); index=1; while(gets(ch),ch[0]!=' ') { creat(k,ch); } while(scanf("%s",ch)!=-1) { int ans=finde(ch); printf("%d ",ans); } return 0; }