字典树(电话列表)

字典树学习:https://blog.csdn.net/weixin_39778570/article/details/81990417

给出一个电话列表,如果列表中存在其中一个号码是另一个号码的前缀这一情况,那么就称这个电话列表是不兼容的。

假设电话列表如下:

·Emergency 911
·Alice 97 625 999
·Bob 91 12 54 26

在此例中,报警电话号码(911)为Bob电话号码(91 12 54 26)的前缀,所以该列表不兼容。

输入格式

第一行输入整数t,表示测试用例数量。

对于每个测试用例,第一行输入整数n,表示电话号码数量。

接下来n行,每行输入一个电话号码,号码内数字之间无空格,电话号码不超过10位。

输出格式

对于每个测试用例,如果电话列表兼容,则输出”YES”。

否则,输出”NO”。

数据范围

1t40,
1n10000

输入样例:

AC代码1:

#include<iostream>
#include<algorithm>
#include<map>
#include<string> 
#include <math.h>
#include<bits/stdc++.h> 
using namespace std;
typedef long long ll; 
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int INF=0x3f3f3f3f;
const int maxn=1e5+10;
char st[10001][10];
int End[maxn],trie[maxn][10],tot;
void insert(char *s){
    int len=strlen(s),p=0;
    for(int i=0;i<len;i++){
        int ch=s[i]-'0';
        if(!trie[p][ch]){
            trie[p][ch]=tot++;
        }
        p=trie[p][ch];
        End[p]++;
    }
}
bool check(char *s){//已经创建该树了,一定会走
    int len=strlen(s);//如果没有走到结束点就return
    int p=0;//说明出现过
    for(int i=0;i<=len-1;i++){
        int ch=s[i]-'0';
        p=trie[p][ch];
        if(End[p]==1){
            return false;//出现过不安全 
        }
    }
    return true; 
} 
int main(){
    int t,n;
    tot=1;
    cin>>t;
    while(t--){
        tot=1;
        memset(trie,0,sizeof(trie)),memset(End,0,sizeof(End));
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%s",st[i]);
            insert(st[i]);
        }
        int flag=1;
        for(int i=1;i<=n;i++){
            if(check(st[i])){
                flag=0;
                break;
            } 
        }
        if(flag==1){
            printf("YES\n");
        } 
        else{
            printf("NO\n");
        }
    }
}

AC代码2:

#include<iostream>
#include<algorithm>
#include<map>
#include<string> 
#include <math.h>
#include<bits/stdc++.h> 
using namespace std;
typedef long long ll; 
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int INF=0x3f3f3f3f;
const int maxn=1e5+10; 
char str[maxn];
int f[maxn],trie[maxn][10],idx; 
int insert(char *str){
    int p=0;
    int is_match=0;//是否和其他的匹配 
    int has_new_node=0;//是否有新节点 
    int len=strlen(str);
    for(int i=0;i<len;i++){
        int u=str[i]-'0';
        if(trie[p][u]==0){//没路创造路 
            trie[p][u]=++idx;
            has_new_node=1; 
        } 
        p=trie[p][u];
        if(f[p]) is_match=1;
    } 
    f[p]++;
    return !is_match&&has_new_node;//没有匹配并且创造过新路 
}
int main(){
    int t;
    int n;
    cin>>t;
    while(t--){
        cin>>n;
        memset(trie,0,sizeof(trie));
        memset(f,0,sizeof(f));
        idx=0;
        int flag=1;
        for(int i=1;i<=n;i++){
            scanf("%s",str);
            if(insert(str)==0){
                flag=0;
            }
        }
        if(flag==0){
            printf("NO\n"); 
        }
        else{
            printf("YES\n");
        } 
    }
}

 

posted @ 2020-02-29 17:05  哎呦哎(iui)  阅读(298)  评论(0编辑  收藏  举报