HDU1251:统计难题

来源:互联网 发布:java数据库连接池写法 编辑:程序博客网 时间:2024/05/22 05:18

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

Input
输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串.

注意:本题只有一组测试数据,处理到文件结束.

Output
对于每个提问,给出以该字符串为前缀的单词的数量.

Sample Input
banana
band
bee
absolute
acm

ba
b
band
abc

Sample Output
2
3
1
0

题目传送门
极其垃圾的一道字典树的题,水的一匹。
字典树这个东西别前面的KMP,EXKMP,Manacher都和善好多啊。
这个代码就打注释了。
字典树的丑样
大概就是这个样子,根节点没有实际意思,每个点的孩子都是字母,有多少字符就最多多少个孩子,从根节点走下去的一条路就是一个字符串
是不是很直接易懂,它的作用性也不低,关键是 代码不长。

#include<cmath>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;struct node{    int s,c[28];    node()    {memset(c,-1,sizeof(c));s=0;}}t[410000];char st[210];int tot;void bt(char *a,int root){    int x=root,len=strlen(a+1);    for(int i=1;i<=len;i++)    {        int y=a[i]-'a'+1;        if(t[x].c[y]==-1)t[x].c[y]=++tot;        x=t[x].c[y];t[x].s++;    }}int Find(int root){    int x=root,len=strlen(st+1);    for(int i=1;i<=len;i++)    {        int y=st[i]-'a'+1;        if(t[x].c[y]==-1)return -1;        x=t[x].c[y];    }    return x;}int main(){    tot=0;    while(gets(st+1))    {        if(st[1]=='\0')break;        bt(st,0);    }    while(gets(st+1))    {        int ans=Find(0);        if(ans==-1)ans=0;        else ans=t[ans].s;        printf("%d\n",ans);    }    return 0;}

by_lmy

原创粉丝点击