POJ 3630:Phone List(字典樹入門)
阿新 • • 發佈:2019-02-11
題目意思:
如果撥打的電話號碼的字首是一個完整的電話號碼,則這個電話就不能撥通,判斷給出的電話列表是否全部能撥通。
這個題目只用再建立字典樹的過程中做判斷就行了,沒必要建完之後再去查詢,我們可以在節點設定count統計某個
節點所代表的單詞當前稱為別人字首的次數。再用個bool變數記錄當前節點所代表的一串字元是不是一個完整的電話
號碼,當一個字串是完整的電話號碼,且被已經加入的串當作字首兩次,這列電話號碼就不能全部撥通。
坑點:
1.不能是用動態連結串列,malloc動態分配記憶體提交會超時,這個題目得用靜態連結串列。
2.靜態連結串列陣列開到一兩萬過不去,儘量開大點,我直接開10萬過了。
AC程式碼:
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> using namespace std; const int maxn = 10; char telNum[10002][14]; struct TrieNode { bool isCompleteTel; int ccount; struct TrieNode *son[maxn]; }node[100000]; int num; TrieNode* createNode() { TrieNode *p = &node[num++]; for(int i = 0; i < maxn; i++) { p->son[i] = NULL; } return p; } ///邊插入Telphone邊判斷。不用建玩樹後再去一個個判斷。 bool insertTel(TrieNode *root,char tel[]) { TrieNode *p; p = root; int i = 0; char ch = tel[i]; while(ch != '\0') { if(p->son[ch-'0'] == NULL) { p->son[ch-'0'] = createNode(); p = p->son[ch-'0']; p->isCompleteTel = false; p->ccount = 1; } else { p->son[ch-'0']->ccount++; p = p->son[ch-'0']; if(p->ccount>1 && p->isCompleteTel==true) ///如果有一串完整電話號碼已經到過這裡了。就不能撥打成功。 return false; } ch = tel[++i]; } p->isCompleteTel = true; if(p->ccount>1 && p->isCompleteTel==true) ///曾經有電話號碼的字首到達過這個電話號碼的結尾了,也不行。 return false; return true; } int main() { int t,n; scanf("%d",&t); while(t--) { num = 0; scanf("%d",&n); bool OK = true; TrieNode *root = createNode(); for(int i = 0; i < n; i++) { scanf("%s",telNum[i]); if(OK) { OK = insertTel(root,telNum[i]); } } if(OK) printf("YES\n"); else printf("NO\n"); } return 0; }