HDU1671(字典树模板题)

来源:互联网 发布:安全知识网络竞赛答题 编辑:程序博客网 时间:2024/05/16 11:35

用struct写的静态字典树,感觉就是链式前向星的思想,原来是这么搞的,恍然大悟。
这个题就是需要加个结尾标记,进行两次判断,第一次判断前面是否存在这个字符串的前缀,第二次判断这个字符串是否为之前出现过的字符串的前缀。
剩下的就是手撕代码了。但是,TT,一定别那么大方了,如同吃了香蕉加大枣。别开100万,别开100万,别开100万,重要的事情说三遍,50万刚刚好。我还不信邪的开了70万试试,刚刚MLE,难受。

#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>#include<iostream>#include<string>#include <set>#include<time.h>//a&3==a%4using namespace std;#define ll long long#define mem(a) memset(a,0,sizeof(a))const double eps=1e-8;const int maxn=500010;//须填写const int inf=0x3f3f3f3f;struct node{    int next[10];    bool isend;    int num;    node()    {        for(int i=0;i<10;i++)        {            next[i]=0;        }        isend=false;        num=0;    }}tree[maxn];int cnt;bool inst(char str[]){    int c;    int index=0;    int len=strlen(str);    for(int i=0;i<len;i++)    {        c=str[i]-'0';        if(tree[index].next[c]==0)        {            tree[index].next[c]=++cnt;        }        index=tree[index].next[c];        tree[index].num++;        if(tree[index].isend)        {            return false;        }        if(i==len-1)        {            tree[index].isend=true;            for(int i=0;i<10;i++)            {                if(tree[tree[index].next[i]].num>0)                    return false;            }        }    }    return true;}int init(){    cnt=0;    mem(tree);    return 1;}int main(){    char str[10010];    int kase;    scanf("%d",&kase);    while(kase--)    {        init();        int n;        scanf("%d",&n);        bool flag=true;        for(int i=0;i<n;i++)        {            scanf("%s",str);            if(flag)                flag=inst(str);        }        if(flag)        {            printf("YES\n");        }        else{            printf("NO\n");        }    }    return 0;}