这题是前几天trie树专题里的一道练习题,那天没有做对。今天重新拿出来,发现是cmp函数写错了。直接用了-strcmp导致排序错误才会WA。改正之后AC
思路就是把给的电话号码按照反字典序排序,再加入trie树。判断是否有串被包含即可。用ok[cur]来判断一个结点被计算了几次。要是插入时的末尾结点被计算过了那就说明存在被包含的串。
代码如下
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int trie[100005][15];
int sz;
int ok[100005];
struct node{
char num[15];
}te[20005];
int cmp(node a,node b){
return strcmp(a.num,b.num)>0;
}
void init(){
memset(trie,0,sizeof(trie));
memset(ok,0,sizeof(ok));
sz = 1;
}
int in(char *s) {
int cur = 1;
for (int i= 0; s[i]; i++) {
int c = s[i]-'0';
if (!trie[cur][c]){
trie[cur][c]= ++sz;
}
cur = trie[cur][c];
ok[cur] ++;
}
if(ok[cur]==1)return 1;
return 0;
}
int main()
{
int T;
cin>>T;
while(T--){
int n;
scanf("%d",&n);
init();
int t = 1;
for(int i=0;i<n;i++)
scanf("%s",te[i].num);
sort(te,te+n,cmp);
for(int i=0;i<n;i++){
if(in(te[i].num)==0)t = 0;
//cout<<t<<endl;
if(!t)break;
}
if(t)printf("YES\n");
else printf("NO\n");
}
return 0;
}