電話列表(字典樹)------------Five-菜鳥級
阿新 • • 發佈:2018-12-24
電話列表
時限:1000 MS
記憶體限制:65536K
提交材料共計:
34731
接受: 9962
描述
給定一個電話號碼列表,確定它是否一致,因為沒有號碼是另一個號碼的字首。假設電話目錄列出了這些號碼:
緊急911
愛麗絲97 625 999
鮑勃91 12 54 26
在這種情況下,不可能打電話給Bob,因為一旦您撥了Bob電話號碼的前三位數,中央就會將您的電話直接打到緊急線路。所以這個名單就不一致了。
輸入
輸入的第一行給出一個整數,1≤t≤40,測試用例的數量。每個測試用例從n,電話號碼,在一條單獨的線路上,1≤。n
≤10000。然後:n每行上有一個唯一電話號碼的線路。電話號碼最多是十位數。輸出量
對於每個測試用例,如果列表一致,輸出“是”,否則輸出“否”。
樣本輸入
2
3
911
97625999
91125426
5
113
12340
123440
12345
98346樣本輸出
NO
YES
題目連結:http://poj.org/problem?id=3630
題解: 這是trie(字典)樹模板題,字典樹插入操作的運用,插入一個單詞是 在單詞最後一個字元打上結束標記。插入新單詞時,不會遇到單詞結束標記,則不會起衝突 滿足條件。
想了解 字典樹(點選即可)
AC程式碼:
#include<stdio.h>
#include<string.h>
#define N 60001
int trie[N][13];
int sum[N]; //存從根節點到單詞(字首)的單詞數
int tot;
int flag;
void insert(char *s){//插入單詞
if(flag) return;//已經衝突了 則不必插入單詞了
int i,id,len,root=0; len=strlen(s);
for(i=0;i<len;i++)
{ id=s[i]-'0';
if(!trie[root][id])trie[root][id]=++tot;//給字元節點編號
root=trie[root][id]; //更新字元節點
if(sum[root]==-1){flag=1;return;}//如果遇到下一個字元節點為某單詞結尾標記 -1 則不符合要求
sum[root]++;
}
if(sum[root]==1)sum[root]=-1;
//在滿足不是字首 單詞最後一個字元為標記為 -1
else flag=1;
}
int main()
{ char s[12]; int T,n;
scanf("%d",&T);
while(T--){
memset(trie,0,sizeof(trie));
memset(sum,0,sizeof(sum));
flag=0;tot=0;
scanf("%d",&n);
while(n--)scanf("%s",&s),insert(s);//輸入單詞表
if(flag==1) printf("NO\n");
else printf("YES\n");
}
return 0;
}