1. 程式人生 > >電話列表(字典樹)------------Five-菜鳥級

電話列表(字典樹)------------Five-菜鳥級

 


                                                       電話列表

時限: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;	
}