(字典树)HDU - 1671 Phone List

Posted tak_fate

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(字典树)HDU - 1671 Phone List相关的知识,希望对你有一定的参考价值。

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1671


题意:给很多电话号码,如果在拨号的时候,拨到一个存在的号码,就会直接打出去,以致以这个号码为前缀的所有其他比这个号码长的号码将不能拨出,问是不是所有的号码都能拨。


分析:可以直接建立字典树,节点中用boolean变量表示当前是否组成电话号码,一旦在遍历完某条号码之前,已经出现存在号码,则发现问题,返回false,否则true。

我使用了一个反过来的方法,即只统计前缀出现次数,遍历完某条号码,如果在当前节点前缀出现的次数cnt>1,则说明还有比这个它更长的号码。

理论上,这两种方法都是可行的,下面贴出第二种方法。


代码:

  1 #include <set>
  2 #include <map>
  3 #include <list>
  4 #include <cmath>
  5 #include <queue>
  6 #include <vector>
  7 #include <bitset>
  8 #include <string>
  9 #include <cctype>
 10 #include <cstdio>
 11 #include <cstring>
 12 #include <cstdlib>
 13 #include <iostream>
 14 #include <algorithm>
 15 
 16 using namespace std;
 17 
 18 typedef long long ll;
 19 typedef unsigned long long ull;
 20 #define inf (0x3f3f3f3f)
 21 #define lnf (0x3f3f3f3f3f3f3f3f)
 22 #define eps (1e-8)
 23 int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}
 24 
 25 //--------------------------
 26 
 27 
 28 struct  Trie_node {
 29     int cnt;
 30     int next[26];
 31 }tree[400010];
 32 int nxt;
 33 
 34 int  createTrieNode() {
 35     memset(&tree[nxt], 0, sizeof(Trie_node));
 36     return nxt++;
 37 }
 38 
 39 void Trie_insert(char* word) {
 40     int rt=0;
 41     int len=strlen(word);
 42     for(int i=0;i<len;i++){
 43         int id = word[i] - 0;
 44         if(!tree[rt].next[id]){
 45             tree[rt].next[id]=createTrieNode();
 46         }
 47         rt=tree[rt].next[id];
 48         tree[rt].cnt++;
 49     }
 50 }
 51 
 52 int Trie_search(char* word) {
 53     int rt=0;
 54     int len=strlen(word);
 55     for(int i=0;i<len;i++){
 56         int id=word[i]-0;
 57         if(!tree[rt].next[id])return 0;
 58         rt=tree[rt].next[id];
 59     }
 60     return tree[rt].cnt;
 61 }
 62 
 63 void init(){
 64     nxt=1;
 65     memset(&tree[0],0,sizeof(Trie_node));
 66 }
 67 
 68 char word[10010][11];
 69 
 70 void solve() {
 71     int t;
 72     scanf("%d",&t);
 73     while(t--){
 74         int n;
 75         scanf("%d",&n);
 76         init();
 77         for(int i=0;i<n;i++){
 78             scanf("%s",word[i]);
 79             Trie_insert(word[i]);
 80         }
 81         bool flag=1;
 82         for(int i=0;i<n;i++){
 83             if(Trie_search(word[i])>1){
 84                 flag=0;
 85                 break;
 86             }
 87         }
 88         if(flag)puts("YES");
 89         else puts("NO");
 90     }
 91 }
 92 
 93 
 94 
 95 
 96 int main() {
 97 
 98 #ifndef ONLINE_JUDGE
 99     freopen("in.txt", "r", stdin);
100     //freopen("out.txt", "w", stdout);
101 #endif
102     //iostream::sync_with_stdio(false);
103     solve();
104     return 0;
105 }

 

以上是关于(字典树)HDU - 1671 Phone List的主要内容,如果未能解决你的问题,请参考以下文章

Phone List HDU - 1671 字典树

hdu 1671 Phone List

Phone List HDU1671

HDU1671 字典树

hdu杭电1671 / poj3630 字典树

HDU1671 水题字典树