zoukankan      html  css  js  c++  java
  • HDU 1671 Phone List(字典树)

                                       Phone List

                                                     Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

                                                                            Total Submission(s): 6772    Accepted Submission(s): 2307

    Problem Description
    Given a list of phone numbers, determine if it is consistent in the sense that no number is the prefix of another. Let’s say the phone catalogue listed these numbers:
    1. Emergency 911
    2. Alice 97 625 999
    3. Bob 91 12 54 26
    In this case, it’s not possible to call Bob, because the central would direct your call to the emergency line as soon as you had dialled the first three digits of Bob’s phone number. So this list would not be consistent.
     
    Input
    The first line of input gives a single integer, 1 <= t <= 40, the number of test cases. Each test case starts with n, the number of phone numbers, on a separate line, 1 <= n <= 10000. Then follows n lines with one unique phone number on each line. A phone number is a sequence of at most ten digits.
     
    Output
    For each test case, output “YES” if the list is consistent, or “NO” otherwise.
     
    Sample Input
    2
    3
    911
    97625999
    91125426
    5
    113
    12340
    123440
    12345
    98346
     
    Sample Output
    NO
    YES
     
     
    题目大意:就是给出一系列的字符串,判断有没有一个字符串是另一个字符串的前缀,没有输出YES,否则输出NO。
         另外这道题要记得内存释放,否则提交后会超内存。
     
      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 
      5 typedef struct _TrieTree
      6 {
      7     bool flag;
      8     struct _TrieTree *next[10];
      9 
     10 }TrieNode;
     11 
     12 TrieNode *CreateTrieTree()   //创建字典树
     13 {
     14     TrieNode *node = (TrieNode *)malloc(sizeof(TrieNode));
     15     node->flag = false;
     16     for(int i = 0; i < 10; i++)
     17         node->next[i] = NULL;
     18 
     19     return node;
     20 }
     21 
     22 void InsertTrieTree(TrieNode *root, char word[]) //插入字符串
     23 {
     24     TrieNode *p = root;
     25     int length = strlen(word);
     26     for(int i = 0; i < length; i++)
     27     {
     28         int index = word[i] - 48;
     29         if(p->next[index] == NULL)
     30         {
     31             p->next[index] = CreateTrieTree();
     32         }
     33         p = p->next[index];
     34     }
     35     p->flag = true;
     36 }
     37 
     38 bool QueryTrieTree(TrieNode *root, char word[])   //查询字符串
     39 {
     40     TrieNode *p = root;
     41     int length = strlen(word);
     42     for(int i = 0; i < length; i++)
     43     {
     44         int index = word[i] - 48;
     45         p = p->next[index];
     46         if(i != length - 1 && p->flag)
     47             return false;
     48     }
     49 
     50     return true;
     51 }
     52 
     53 void FreeTrieTree(TrieNode *root)     //递归释放每个字典树的内存
     54 {
     55     TrieNode *p = root;
     56     if(p != NULL)
     57     {
     58         for(int i = 0; i < 10; i++)
     59         {
     60             if(p->next[i] != NULL)
     61                 FreeTrieTree(p->next[i]);
     62         }
     63         delete p;
     64         p = NULL;
     65     }
     66 }
     67 
     68 int main()
     69 {
     70     int T, n;
     71     const int MAX_NUM = 10005;
     72     char  word[MAX_NUM][11];
     73     
     74     scanf("%d", &T);
     75     while(T--)
     76     {
     77         TrieNode *root = CreateTrieTree();
     78 
     79         scanf("%d", &n);
     80         getchar();
     81         for(int i = 0; i < n; i++)
     82         {
     83             scanf("%s", word[i]);
     84             InsertTrieTree(root, word[i]);
     85         }
     86 
     87         bool bResult = true;
     88         for(int i = 0; i < n; i++)
     89         {
     90             bResult = QueryTrieTree(root, word[i]);
     91             if(!bResult)
     92                 break;
     93         }
     94 
     95         if(bResult)
     96             printf("YES\n");
     97         else
     98             printf("NO\n");
     99 
    100         FreeTrieTree(root);
    101     }
    102 
    103     return 0;
    104 }

    然后,看到网上有的是在插入的过程中进行判断的,若在插入的过程中就已经判断出来有不符合条件的前缀字符串,

    则剩余的未输入的字符串就不再插入到字典树中,减少部分时间开销。

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <string.h>
     4 
     5 typedef struct _TrieTree
     6 {
     7     bool flag;
     8     struct _TrieTree *next[10];
     9 
    10 }TrieNode;
    11 
    12 TrieNode *CreateTrieTree()   //创建字典树
    13 {
    14     TrieNode *node = (TrieNode *)malloc(sizeof(TrieNode));
    15     node->flag = false;
    16     for(int i = 0; i < 10; i++)
    17         node->next[i] = NULL;
    18 
    19     return node;
    20 }
    21 
    22 bool InsertTrieTree(TrieNode *root, char word[]) //插入字符串
    23 {
    24     TrieNode *p = root;
    25     int length = strlen(word);
    26     for(int i = 0; i < length; i++)
    27     {
    28         int index = word[i] - 48;
    29         if(p->next[index] == NULL)
    30         {
    31             p->next[index] = CreateTrieTree();
    32         }
    33         p = p->next[index];
    34         if(p->flag)              //有字符串是它的前缀
    35             return false;
    36     }
    37     for(int i = 0; i < 10; i++)
    38         if(p->next[i] != NULL)   //它是别的字符串的前缀
    39             return false;
    40 
    41     p->flag = true;
    42     return true;
    43 }
    44 
    45 void FreeTrieTree(TrieNode *root)     //递归释放每个字典树的内存
    46 {
    47     TrieNode *p = root;
    48     if(p != NULL)
    49     {
    50         for(int i = 0; i < 10; i++)
    51         {
    52             if(p->next[i] != NULL)
    53                 FreeTrieTree(p->next[i]);
    54         }
    55         free(p);
    56         p = NULL;
    57     }
    58 }
    59 
    60 int main()
    61 {
    62     int T, n;
    63     const int MAX_NUM = 10005;
    64     char  word[MAX_NUM][11];
    65     
    66     scanf("%d", &T);
    67     while(T--)
    68     {
    69         TrieNode *root = CreateTrieTree();
    70 
    71         bool bResult = true;
    72         scanf("%d", &n);
    73         getchar();
    74         for(int i = 0; i < n; i++)
    75         {
    76             scanf("%s", word[i]);
    77             if(!bResult)              //若插入的过程中,已判断不符合条件
    78                 continue;             //就跳过,不再插入
    79             if(!InsertTrieTree(root, word[i]))
    80                 bResult = false;
    81         }
    82 
    83         if(bResult)
    84             printf("YES\n");
    85         else
    86             printf("NO\n");
    87 
    88         FreeTrieTree(root);
    89     }
    90 
    91     return 0;
    92 }

    另外还有一种方法,先对所有字符串进行排序,然后比较相邻两个字符串,若前一个字符串是后一个字符串的前缀,

    就输出NO,否则输出YES。

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <stdlib.h>
     4 
     5 typedef struct _PHONE
     6 {
     7     char word[11];
     8 
     9 }PHONE;
    10 
    11 int cmp(const void *a, const void *b)
    12 {
    13     return strcmp( (*(PHONE *)a).word, (*(PHONE *)b).word );
    14 }
    15 
    16 int main()
    17 {
    18     int T, n;
    19     const int MAX_NUM = 10005;
    20     PHONE phone[MAX_NUM]; 
    21 
    22     scanf("%d", &T);
    23     while(T--)
    24     {
    25         scanf("%d", &n);
    26         for(int i = 0; i < n; i++)
    27             scanf("%s", phone[i].word);
    28 
    29         qsort(phone, n, sizeof(PHONE), cmp);
    30 
    31         bool bResult = true;
    32         for(int i = 0; i < n - 1; i++)
    33         {
    34             char *p = strstr(phone[i + 1].word, phone[i].word);
    35             if(p != NULL)
    36             {
    37                 bResult = false;
    38                 break;
    39             }
    40         }
    41         if(bResult)
    42             printf("YES\n");
    43         else
    44             printf("NO\n");
    45     }
    46 
    47     return 0;
    48 }
  • 相关阅读:
    HTML5 学习笔记(三)——本地存储(LocalStorage、SessionStorage、Web SQL Database)
    HTML5 学习笔记(二)——HTML5新增属性与表单元素
    apache 运行一段时间出现错误
    先验算法(Apriori algorithm)
    Opera官网打不开 下载Opera最新版本的实际地址
    网址查看浏览器内核版本
    小鸟云四个数据中心介绍
    nilcms file类 简单文件缓存实现
    小鸟云优惠券 云服务器介绍
    PHP中测试in_array、isset、array_key_exists性能
  • 原文地址:https://www.cnblogs.com/Dreamcaihao/p/3096265.html
Copyright © 2011-2022 走看看