POJ 3630 Phone List(trie树的简单应用)
题目链接:http://poj.org/problem?id=3630
题意:给你多个字符串,如果其中任意两个字符串满足一个是另一个的前缀,那么输出NO,否则输出YES
思路:简单的trie树应用,插入的过程中维护到当前节点是不是字符串这个布尔量即可,同时判断是否存在上述情况。
code:
1 #include <iostream> 2 #include <cstdio> 3 #include <string> 4 #include <cstring> 5 using namespace std; 6 7 const int KIND = 10; 8 const int MAXN = 100005; 9 struct trie 10 { 11 bool isString; // 标志到当前节点是否是字符串 12 trie* next[KIND]; 13 trie() 14 { 15 isString = false; 16 for (int i = 0; i < KIND; ++i) next[i] = NULL; 17 } 18 }; 19 20 trie node[MAXN]; 21 trie* root; 22 bool flag; 23 int k; 24 25 void Insert(string ss) 26 { 27 trie* temp = root; 28 int len = ss.size(); 29 for (int i = 0; i < len; ++i) 30 { 31 int curr = ss[i] - '0'; 32 if (temp->next[curr] != NULL) // 判断前缀在前面出现的情况 33 { 34 if (temp->next[curr]->isString) 35 { 36 flag = false; 37 return; 38 } 39 } 40 else temp->next[curr] = &node[k++]; 41 temp = temp->next[curr]; 42 } 43 temp->isString = true; 44 for (int i = 0; i < KIND; ++i) // 判断前缀在后面出现的情况 45 { 46 if (temp->next[i]) 47 { 48 flag = false; 49 return; 50 } 51 } 52 } 53 54 int main() 55 { 56 int nCase; 57 cin >> nCase; 58 while (nCase--) 59 { 60 flag = true; 61 k = 1; 62 memset(node, 0, sizeof(node)); 63 root = &node[0]; 64 65 int n; 66 cin >> n; 67 68 string str; 69 for (int i = 0; i < n; ++i) 70 { 71 cin >> str; 72 if (flag) Insert(str); 73 } 74 if (flag) cout << "YES" << endl; 75 else cout << "NO" << endl; 76 } 77 return 0; 78 }