Trie树【UVA11362】Phone List

本文介绍了一道关于Trie树的经典问题:判断多个数字串中是否存在互为前缀的情况。通过定义ok[v]数组标记字符串结尾,cnt[u]记录节点遍历次数,巧妙地解决了问题,并附带源代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

给定\(n\)个长度不超过\(10\)的数字串,判断是否有两个字符串\(A\)\(B\),满足\(A\)\(B\)的前缀,若有,输出NO,若没有,输出YES

一道\(Trie\)树裸题,我交了20次.

呜呜呜呜,难受.

刚开始是看错题,有的话输出"NO",没有输出“YES”什么鬼题啊!!!

一眼看到就会切了的.害得我交了20次啊!

定义数组:

  \(ok[v]\)表示以\(v\)为结尾的字符串是否出现过.

  \(cnt[u]\)代表当前节点被遍历过几次,判断插入的某字符串的末尾是否被经历过两次以上.

输出即可.

记得\(memset\).

代码

#include<cstdio>
#include<cstring>
#define clear(a) memset(a,0,sizeof a) 
#define R register
using namespace std;
int tri[100005][12],n,T,rt,tot,cnt[100005];
char s[15];
bool flg,ok[100005];
inline void insert(int u,char *s)
{
    int len=strlen(s);
    for(R int i=0;i<len;i++)
    {
        int v=s[i]-'0';
        if(!tri[u][v])
            tri[u][v]=++tot;
        u=tri[u][v];
        cnt[u]++;
        if(ok[u])flg=true;
    }
    ok[u]=true;
    if(cnt[u]>1)flg=true;
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        flg=false;
        clear(tri);clear(ok);
        clear(cnt);tot=0;
        scanf("%d",&n);
        for(R int i=1;i<=n;i++)
        {
            scanf("%s",s);
            insert(rt,s);   
        }
        puts(flg?"NO":"YES");
    }
}

转载于:https://www.cnblogs.com/-guz/p/9788195.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值