【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 
T

这道题是比较水的统计以此为前缀的单词数量

就是在插入的时候路径上cnt++,然后输出时候前缀走到底输出cnt值就OK了

注意一点

就是如果这个前缀不存在,会跳到0,然后就错了

所以当发现下一个字母不存在的时候直接返回0就能行

这道题的输入比较坑

有一个换行

这里用的gets可以吃掉除换行以外的东西,然后如果有换行,就读不进来,所以就是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
",find(in+1));
43     return 0;
44 }
原文地址:https://www.cnblogs.com/Qin-Wei-Kai/p/10209089.html