【trie树】HDU1251统计难题
统计难题 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131070/65535 K (Java/Others) Total Submission(s): 60040 Accepted Submission(s): 20857 Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀). Input 输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串. 注意:本题只有一组测试数据,处理到文件结束. Output 对于每个提问,给出以该字符串为前缀的单词的数量. Sample Input banana band bee absolute acm ba b band abc Sample Output 2 3 1 0 Author Ignatius.L Recommend Ignatius.L | We have carefully selected several similar problems for you: 1075 1247 1671 1298 1800
这道题是比较水的统计以此为前缀的单词数量
就是在插入的时候路径上cnt++,然后输出时候前缀走到底输出cnt值就OK了
注意一点
就是如果这个前缀不存在,会跳到0,然后就错了
所以当发现下一个字母不存在的时候直接返回0就能行
这道题的输入比较坑
有一个换行
这里用的gets可以吃掉除换行\0以外的东西,然后如果有换行,就读不进来,所以就是NULL
getchar应该是一个一个字符吃,可以试一试
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #define idx(i) (i-'a') 5 #define N 1000006 6 using namespace std; 7 char in[20]; 8 int cnt=1; 9 struct TRIE{int nxt[30],cnt;}tree[N]; 10 inline int regist(){return cnt++;} 11 void insert(char *now) 12 { 13 int c,rt=0,len=strlen(now); 14 for(int i=0;i<len;i++) 15 { 16 c=idx(now[i]); 17 if(!tree[rt].nxt[c]) 18 tree[rt].nxt[c]=regist(); 19 rt=tree[rt].nxt[c]; 20 tree[rt].cnt++; 21 } 22 } 23 int find(char *now) 24 { 25 int rt=0,len=strlen(now); 26 for(int i=0;i<len;i++) 27 { 28 if(!tree[rt].nxt[idx(now[i])])return 0; 29 rt=tree[rt].nxt[idx(now[i])]; 30 } 31 return tree[rt].cnt; 32 } 33 int main() 34 { 35 while(1) 36 { 37 gets(in+1); 38 if(in[1]==NULL)break; 39 insert(in+1); 40 } 41 while(scanf("%s",in+1)!=EOF) 42 printf("%d\n",find(in+1)); 43 return 0; 44 }