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




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值