题目要求找是否出现电话号码是其他号码的前缀,是一个字典树的经典题
按字典序从大到小排序,如果能在之前的树里找到,那么输出NO
只要稍微改一下search函数的返回值,不用判断是否是结束节点,所以并没必要开vis数组…
原版的search函数返回值是return vis[p]==1
,表示结尾是结束节点,但是本题不需要,直接改成return 1;
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int trie[100005][26]={0};
int vis[100005]={0};
string s[100005];
int k=1;
void insert(string w)
{
int len=w.length();
int p=0;
for(int i=0;i<len;i++)
{
int c=w[i]-'0';
if(!trie[p][c])
{
trie[p][c]=k;
k++;
}
p=trie[p][c];
}
vis[p]=1;
}
int search(string ss)
{
int len=ss.length();
int p=0;
for(int i=0;i<len;i++)
{
int c=ss[i]-'0';
if(!trie[p][c]) return 0;
p=trie[p][c];
}
return 1;
}
int main()
{
int t;
cin>>t;
while(t--)
{
memset(vis,0,sizeof(vis));
memset(trie,0,sizeof(trie));
k=1;
int n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>s[i];
}
sort(s,s+n);
int flag=1;
for(int i=n-1;i>=0;i--)
{
if(search(s[i])==0) insert(s[i]);
else
{
printf("NO\n");
flag=0;
break;
}
}
if(flag==1) printf("YES\n");
}
return 0;
}