題目大意是給定t組數據,每組中有n個數字構成的字符串電話號碼,要求對每一組數據判斷是否存在一個電話號碼爲另一個的前綴,如果有,則這一組數據不合要求,輸出”NO”,若是沒有,就是”YES”。
一眼就看出來這道題是一個裸的trie樹問題,需要利用trie樹這種結構判斷是否存在前綴即可。
用trie樹先記錄每個電話號碼,並將它們最末一位存下來,之後遍歷所有電話號碼的最末一位,如果某一個有子結點,就說明它所對應的電話號碼爲另一個的前綴。若均沒有,則不存在一個電話號碼爲另一個的前綴。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=100009;
const int inf = 0x3f3f3f3f;
int n;
int tree[N][10],tot;
bool p[N];
int trie(char w[])
{
int loc=0;//0號結點是虛擬的根結點
for (int i=0;w[i];i++)//把號碼的每一位都在樹上走一遍
{
int x=tree[loc][w[i]-'0'];
if (x==-1)//如果下一位數字的位置還未出現過,新建一個結點並編號
tree[loc][w[i]-'0']=++tot;
loc=tree[loc][w[i]-'0'];//繼續走下一位數字
}
return loc;//返回最末一位數字
}
int main()
{
int c;
for (scanf ("%d",&c);c--;)
{
memset (tree,-1,sizeof(tree));
memset (p,false,sizeof(p));
tot=0;
scanf ("%d",&n);
for (int i=1;i<=n;i++)
{
char s[21];
scanf ("%s",s);
p[trie(s)]=true;//將號碼最後一個數字編號記錄下
}
bool k=false;
for (int i=1;i<=tot;i++)
{
if (p[i]==true)//查詢每個電話號碼的最後一位
{
for (int j=0;j<=9;j++)
if (tree[i][j]!=-1)//如果發現某個電話號碼的最後一位有子結點,則存在前綴
{
k=true;
break;
}
}
}
if(k)
puts("NO");
else
puts("YES");
}
return 0;
}