hdu 1671 字典树问题 TIRE树

题目链接

重新码一遍字典树会对字典树有着更深的印象,原来是直接动态开辟的空间,觉得这样的方法好麻烦,自己借鉴代码写的利用已知存储空间来求字典树。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;
const int max_child=200000;
const int char_set=26;
const char base='0';   //注意这里是基数 是0 抄代码时直接看成是a了 导致错误。
const int input=20000;

char a[input][20];
struct Tire{
     int tot,root,child[max_child][char_set];
     int flag[max_child];
     Tire(){
        tot=1;
        root=1;
        memset(child[1],0,sizeof(child[1]));
        flag[0]=0;
     }
     void reset(int n){     //直接reset恢复原状。
         root=1;
         tot=1;
         memset(child[1],0,sizeof(child[1]));
         memset(flag,0,sizeof(int)*n*10);

     }
     void insert(char *str){    //查询
        int *cur=&root;
        for (char *p=str;*p;p++){
            cur=&child[*cur][*p-base];
            if (*cur==0){
                *cur=++tot;
                memset(child[*cur],0,sizeof(child[*cur]));
            }
            flag[*cur]++;   //这里一定要是*cur 因为重复计数的也要将flag中的值加1  例如 aaa和aaaaa要依次相加
            //printf("%d %d %d\n",*cur,tot,flag[*cur]);   //这是输出测试结果的代码。
        }
     }
     int query(char *str){             //询问。
        int *cur=&root;
        for (char *p=str;*p;p++){
            cur=&child[*cur][*p-base];
        }
        //printf("%d flag[*cur]=%d\n",*cur,flag[*cur]);
        if(flag[*cur]!=1)return 1;  //存在
        else return 0;
     }
} tree;

int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        int n;
        scanf("%d",&n);
        tree.reset(n);
        for(int i=1;i<=n;i++){
           scanf("%s",a[i]);
           tree.insert(a[i]);
        }
        int flag=0;
        for(int i=1;i<=n;i++){
           flag=tree.query(a[i]);
           //printf("roud=%d %d\n",i,flag);
           if(flag==1)break;
        }
        if(flag==1)printf("NO\n");
        else printf("YES\n");
    }
    return 0;
}




你可能感兴趣的:(算法)