1027: 教你前缀
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 29 Solved: 6
[ Submit][ Status][ Web Board]
Description
什么是前缀你懂吧,不懂?那我告诉你,假如串S1和S2长度分别是len1,len2,len1<=len2且S2的前len1个字母和S1一样,则S1是S2的前缀。CJR不是在给叶老师做项目嘛,今天遇到一个小问题,找到wuyu,wuyu也不会做,那就请教你来了。叶老师给他很多全是英文小写字母字符串,要她统计一下这里面有多少个串可以做其他串的前缀,重复的串只统计一次。
Input
正整数n,(n<=40000),然后输入n个字符串,每个字符串长度不超过10个字符。
Output
一行,表示这些串里面能做其他串前缀的串的个数。
Sample Input
6 ababa aba bab ab b ab 2 abc abc
Sample Output
3 1
思路:节点除了一般内容外,存储这个节点是否有子节点,也就是当给它增加子节点时修改该节点布尔值;另外存储以该节点为终点的单词数量。最后扫描所有节点,统计其有子节点并且以该节点为终点的单词书不为0,或者该节点为2个以上单词的终点节点个数即可。
#include<cstdio>
#include<cstring>
using namespace std;
int cnt;
struct node
{
char x;
int c[26],n;
bool s;
void nod1(){memset(c,-1,sizeof(c));n=0;s=false;}
}t[130000];
void insert(char s[12])
{
int now=s[0]-'a',len=strlen(s),i;
for(i=1;i<len;i++)
{
if(t[now].c[s[i]-'a']==-1)
{
t[cnt].nod1();
t[cnt].x=s[i];
t[now].c[s[i]-'a']=cnt;
t[now].s=true;
now=cnt++;
}
else
{
now=t[now].c[s[i]-'a'];
}
}
t[now].n++;
}
int main()
{
char ipt[12];
int n,len,i,j,ans;
while(scanf("%d",&n)==1)
{
for(i=0;i<26;i++)
t[i].nod1();
cnt=26;ans=0;
for(j=0;j<n;j++)
{
scanf("%s",ipt);
insert(ipt);
}
for(i=0;i<cnt;i++)
if((t[i].s&&t[i].n)||t[i].n>1) ans++;
printf("%d\n",ans);
}
return 0;
}