字典树学习: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”。
数据范围
1≤t≤40,
1≤n≤10000
输入样例:
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"); } } }