HDU 1671 trie树

传送门:hdu 1671

题解

  1. 插入时查找, 判断当前串是否是已插入字符串集的字串或者是已插入的某字符串是它的字串
  2. 静态数组实现

AC code

/*
* Author : adrui
* Language : C++
* Result : Accepted
* Love : yy
* Favorite : Dragon Balls

* Standing in the Hall of Fame
*/


#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<iostream>
using namespace std;

#define debug 0
#define LL long long
#define inf 0x7f7f7f7f
#define mod 10003
#define mid ((l + r) >> 1)
#define ls rt << 1, l, mid
#define rs rt << 1|1, mid + 1, r
#define M(a, b) memset(a, b, sizeof(a))

const int maxn(1e5 + 5);

int n;
int ch[maxn][15], val[maxn];

int idx(char p) {
    return p - '0';
}

struct trie {
    int sz;

    trie() {
        sz = 1;
        M(ch, 0);
        M(val, 0);
    }

    void insert(char *s, int &flag) {
        int len = strlen(s), u = 0;

        for (int i = 0; i < len; ++i) {
            int c = idx(s[i]);
            if (!ch[u][c]) {
                ch[u][c] = sz++;                    //新建结点
            }
            u = ch[u][c];                           
            if (val[u]) {                           //判断已插入串集中有没有s的字串
                flag = 1; break;
            }
        }

        val[u] = 1;                                 //串结束表示

        for (int i = 0; i < 10; ++i)                //判断s是不是已插入串集中某串的字串
            if (ch[u][i]) {
                flag = 1;
                break;
            }

    }
};

int main() {
#if debug
    freopen("in.txt", "r", stdin);
#endif //debug

    cin.tie(0);
    cin.sync_with_stdio(false);


    int T;
    cin >> T;

    char s[15];

    while (T--) {
        trie root;
        cin >> n;
        int flag = 0;

        for (int i = 0; i < n; ++i) {
            cin >> s;
            if (flag) continue;                     //找到
            root.insert(s, flag);
        }

        if (flag) cout << "NO" << endl;
        else cout << "YES" << endl;
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值