hihoCoder1107 Shortest Proper Prefix Tire树

来源:互联网 发布:网站数据分析方法 编辑:程序博客网 时间:2024/05/21 07:10

题目链接:hihoCoder1107


题目大意:给你n个字符串,定义proper prefix为其中某个字符串s的前缀满足:在这n个字符串中出现的次数不超过5次;定义shortest proper prefix为其中某个字符串s满足:s是proper prefix且s的所有前缀(不包括s本身)都不是proper prefix.现在让找出这n个字符串中shortest proper prefix的个数。



分析:以这n个字符串建立一颗字典树,从根节点开始往下遍历,如果满足当前节点的num值不大于5且不为0(不为0保证了该前缀出现过),那么计数器加1,同时不再往下遍历,改而遍历该节点的兄弟节点,知道遍历所以的节点为止。


实现代码如下:

#include <cstdio>#include <cstdlib>#include <iostream>using namespace std;#define son_num 30 //字符串中包含的字符个数#define maxn 2000010 //单词的最大长度struct tire{    int num; //纪录到达该节点的字符串的个数,即相同前缀数    struct tire *next[son_num]; //纪录下一个节点};tire *root;char str0[maxn];int ans;tire *init() //创建新节点{    tire *p=(tire *)malloc(sizeof(tire));    for(int i=0;i<son_num;i++)      p->next[i]=NULL;    p->num=0;    return p;}void insert(tire *root,char str[]) //插入操作{    int i=0;    tire *p=root;    while(str[i]!='\0')    {        if(!p->next[ str[i]-'a' ]) //如果不存在,建立新节点          p->next[ str[i]-'a' ]=init();        p=p->next[ str[i]-'a' ];        p->num++;        i++;    }}void solve(tire *node){    tire *p=node;    if(p->num<=5&&p->num!=0)    {        ans++;        return ;    }    for(int i=0;i<son_num;i++)      if(p->next[i]) solve(p->next[i]);}void del(tire *root) //清空操作{    for(int i=0;i<son_num;i++)      if(root->next[i]!=NULL)        del(root->next[i]);    free(root);}int main(){    root=init();  //创建根结点    int n; //n为建立字典树的单词数    cin>>n;    ans=0;    for(int i=0;i<n;i++) //建立字典树    {        scanf("%s",str0);        insert(root,str0);    }    solve(root);    printf("%d\n",ans);    del(root); //释放字典树占用的空间    return 0;}


0 0