題目 總覺得那個電話??(大霧)有點滑稽。
題目大意
給定n個長度不超過10的數字串。
問其中是否存在兩個數字串S,T。
使得S是T的前綴,多組數據。
對於100%的數據,1<=t<=40,1<=n<=10^4。
題目分析
一邊建樹一邊做。
兩種情況:
- 如果這個單詞建樹時沒有插入任何新節點,那麼這個單詞是別的單詞的前綴
- 如果這個單詞建樹時經過的某個節點是某個單詞的結尾,那麼以這個單詞結尾的單詞是這個單詞的前綴
我再說一遍我不是在繞口令。嚴肅臉。
以上。
代碼
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int len=0,kkk;
struct node{int son[20],end;}tr[6000010];
void bt(char s[],int ss)
{
int now=1; bool q=false;//q用來判斷是否符合情況1
for(int i=1;i<=ss;i++)
{
if(tr[now].son[s[i]-'0'])//第2種情況
{
now=tr[now].son[s[i]-'0'];
if(tr[now].end) kkk=false;
}
else
{
len++; tr[now].son[s[i]-'0']=len;
now=len; tr[now].end=0; q=true;
//如果插入了新節點,那麼不符合情況1
}
}
tr[now].end++;
if(!q) kkk=false;//符合情況1
}
int main()
{
int t; scanf("%d",&t);
while(t--)
{
memset(tr[1].son,0,sizeof(tr[1].son));
kkk=true;
int n; scanf("%d",&n);
for(int i=1;i<=n;i++)
{
char s[20]; scanf("%s",s+1);
bt(s,strlen(s+1));
}
if(kkk) printf("YES\n");
else printf("NO\n");
}
return 0;
}