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 }

 

posted @ 2015-06-08 11:35  jasaiq  阅读(324)  评论(0编辑  收藏  举报