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 }

 

你可能感兴趣的:(list)