CCNUOJ 1027 教你前缀

1027: 教你前缀

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 29  Solved: 6
[Submit][Status][Web Board]

Description

什么是前缀你懂吧,不懂?那我告诉你,假如串S1S2长度分别是len1len2len1<=len2S2的前len1个字母和S1一样,则S1S2的前缀。CJR不是在给叶老师做项目嘛,今天遇到一个小问题,找到wuyuwuyu也不会做,那就请教你来了。叶老师给他很多全是英文小写字母字符串,要她统计一下这里面有多少个串可以做其他串的前缀,重复的串只统计一次。

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;
}

  

posted @ 2011-07-30 00:06  laputastar  阅读(193)  评论(0编辑  收藏  举报