hdu-1251 统计难题---字典树

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=1251

题目大意:

Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).

 解题思路:
将每个单词存入字典树中,直接查询前缀出现次数即可,在加入字典树的时候,在每个字母表示的边上后面的节点数加1,记录前缀出现次数。
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<string>
 5 #include<map>
 6 #include<set>
 7 #include<cmath>
 8 #include<algorithm>
 9 #include<vector>
10 #include<sstream>
11 #define lowbot(i) (i&(-i))
12 using namespace std;
13 
14 const int maxn = 1e6 + 10;
15 int tree[maxn][26];
16 //字典树tree[u][v]表示编号为u的节点的下一个字母为v连接的节点的编号
17 int idx(char c){ return c - 'a'; }//可以写成宏定义
18 int tot = 1;//根节点编号为1
19 int sum[maxn];//标记以该节点结束的前缀出现次数
20 void Insert(char s[], int u)//u表示根节点
21 //插入字符串s
22 {
23     for(int i = 0; s[i]; i++)
24     {
25         int c = idx(s[i]);
26         if(!tree[u][c])
27             tree[u][c] = ++tot;
28         sum[tree[u][c]]++; //前缀后面的那个节点数目加一
29         u = tree[u][c];
30     }
31 }
32 
33 int Find_sum(char s[], int u)
34 {
35     for(int i = 0; s[i]; i++)
36     {
37         int c = idx(s[i]);
38         if(!tree[u][c])return 0;
39         u = tree[u][c];
40     }
41     return sum[u];//返回最后一个字母表示的边连接的后面那个节点,所记录的sum值
42 }
43 int main()
44 {
45     char s[15];
46     while(gets(s) && strlen(s))Insert(s, 1);
47     while(scanf("%s", s) != EOF)
48     {
49         printf("%d\n", Find_sum(s, 1));
50     }
51     return 0;
52 }

 

 
posted @ 2018-04-26 11:55  _努力努力再努力x  阅读(134)  评论(0编辑  收藏  举报