给出一个电话列表,如果列表中存在其中一个号码是另一个号码的前缀这一情况,那么就称这个电话列表是不兼容的。
假设电话列表如下:
·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≤401≤t≤40,
1≤n≤100001≤n≤10000
输入样例:
2
3
911
97625999
91125426
5
113
12340
123440
12345
98346
输出样例:
NO
YES
题意:让你判断电话列表有没有矛盾
思路:前缀判断,我们用trie,首先我们存下每个串最后出现的位置+1,然后后面的字符串遍历的时候,如果路径上有过+1,说明有字符串在这里终止成为了这个串的前缀,所以为NO
因为判断时判断前面的能不能成为后面串的前缀,所以我们首先按照长度从小到大排序、
#include<bits/stdc++.h> #define maxn 100005 #define mod 1000000007 using namespace std; int ch[maxn][10]; int dp[maxn]; string str[maxn]; int tot=1; int insert(string s){ int p=1; for(int i=0;i<s.size();i++){ int k=s[i]-'0'; if(ch[p][k]==0) ch[p][k]=++tot; p=ch[p][k]; //dp[p]++; if(dp[p]) return 0; } dp[p]++; return 1; } int cmp(string x,string y){ return x.size()<y.size(); } int main(){ int t,n; scanf("%d",&t); while(t--){ scanf("%d",&n); tot=1; memset(ch,0,sizeof(ch)); memset(dp,0,sizeof(dp)); int flag=1; for(int i=0;i<n;i++){ cin>>str[i]; } sort(str,str+n,cmp); for(int i=0;i<n;i++){ int k=insert(str[i]); if(k==0){ flag=0; } } if(flag) printf("YES\n"); else printf("NO\n"); } }