poj3630 Phone List【Trie树】

Phone List

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 34805   Accepted: 9980

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:

  • Emergency 911
  • Alice 97 625 999
  • 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

Source

Nordic 2007

题意:

给n个最多是10位的电话号码,问存不存在某个电话号码是其他电话号码的前缀的情况。存在输出NO,否则输出YES

思路:

最开始的思路是先给所有的字符按照字符串的长度从短到长排个序,一次将字符串添加到Trie树中。添加过程中如果发现某个节点已经被标记为字符串结束,那么说明要输出NO。这样的思路TLE。大概是因为对于每一个字符串都要先求一下长度然后排序的话就变成了O(n^2logn)?

其实我们并不需要排序。只需要在建立Trie树的时候对节点的出现次数进行统计。并且,一条路径上靠近根节点的节点的次数一定是大于等于远离根节点的。建立完成后我们对于每一个字符串,去找他在树上的这个路径是不是全部都是次数大于1的节点。只要找到一个路径全部都是大于1的节点的路径说明这个字符串是某个字符串的前缀。输出NO

  1 #include <iostream>
  2 #include <set>
  3 #include <cmath>
  4 #include <stdio.h>
  5 #include <cstring>
  6 #include <algorithm>
  7 #include <vector>
  8 #include <queue>
  9 #include <map>
 10 using namespace std;
 11 typedef long long LL;
 12 #define inf 0x7f7f7f7f
 13
 14 int t, n;
 15 const int maxn = 1e5 + 5;
 16 int ed[maxn];
 17 int trie[maxn][10], tot = 1;
 18 //vector<string>s;
 19 //string s[maxn];
 20 char s[maxn][10];
 21
 22 void insertt(char* str)
 23 {
 24     int len = strlen(str), p = 1;
 25     for(int k = 0; k < len; k++){
 26         int ch = str[k] - ‘0‘;
 27         if(trie[p][ch] == 0){
 28             trie[p][ch] = tot++;
 29         }
 30         p = trie[p][ch];
 31         ed[p]++;
 32     }
 33     //ed[p] = true;
 34     //ed[p] = true;
 35 }
 36
 37 bool searchh(char *str)
 38 {
 39     int len = strlen(str), p = 19;
 40     for(int k = 0; k < len; k++){
 41         p = trie[p][str[k] - ‘0‘];
 42         if(ed[p] == 1){
 43             return false;
 44         }
 45     }
 46     return true;
 47 }
 48
 49 bool cmp(string a, string b)
 50 {
 51     return a.size() > b.size();
 52     //return strlen(a) > strlen(b);
 53 }
 54
 55 int main()
 56 {
 57     scanf("%d", &t);
 58     while(t--){
 59         tot = 1;
 60         memset(trie, 0, sizeof(trie));
 61         memset(ed, 0, sizeof(ed));
 62         scanf("%d", &n);
 63         for(int i = 0; i < n; i++){
 64             /*char c[10];
 65             string ch;
 66             scanf("%s", c);
 67             ch = c;
 68             s.push_back(ch);
 69             //cin>>s[i];*/
 70             scanf("%s", &s[i]);
 71             insertt(s[i]);
 72         }
 73         //sort(s.begin(), s.end(), cmp);
 74         /*for(int i = 0; i < n; i++){
 75             cout<<s[i]<<endl;
 76         }*/
 77         bool flag = true;
 78         for(int i = 0; i < n; i++){
 79             if(searchh(s[i])){
 80                 flag = false;
 81                 break;
 82             }
 83             /*if(searchh((char*)s[i].data())){
 84                 printf("NO\n");
 85                 flag = false;
 86                 break;
 87             }
 88             else{
 89                 insertt((char*)s[i].data());
 90             }*/
 91         }
 92         if(flag){
 93             printf("YES\n");
 94         }
 95         else{
 96             printf("NO\n");
 97         }
 98     }
 99     return 0;
100 }

原文地址:https://www.cnblogs.com/wyboooo/p/9838235.html

时间: 2024-10-11 01:36:43

poj3630 Phone List【Trie树】的相关文章

poj3630 Phone List (trie树模板题)

Phone List Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 26328   Accepted: 7938 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 catalogu

Trie树 poj3630

题目链接 题目描述 有n个电话号码,长度对多为10个,问存不存在一个电话号码是另一个的前缀,是就输出NO,否则YES. 1. n<104 思路 Trie树裸题 1. 把所有字符串插入Trie树 2. 插入时进行以下判断: a. 当前插入的字符串可以沿着Tries树中的某条路径一直往下走,不用新开节点:可能比这条路径表示的字符串长,即最后才新开节点.可能比它短,即当前插入字符串读完后,Tries树的这条路径还可延伸. b. Trie树的这条路径没走完就新开节点,显然就不是前缀 代码 #includ

跳跃表,字典树(单词查找树,Trie树),后缀树,KMP算法,AC 自动机相关算法原理详细汇总

第一部分:跳跃表 本文将总结一种数据结构:跳跃表.前半部分跳跃表性质和操作的介绍直接摘自<让算法的效率跳起来--浅谈"跳跃表"的相关操作及其应用>上海市华东师范大学第二附属中学 魏冉.之后将附上跳跃表的源代码,以及本人对其的了解.难免有错误之处,希望指正,共同进步.谢谢. 跳跃表(Skip List)是1987年才诞生的一种崭新的数据结构,它在进行查找.插入.删除等操作时的期望时间复杂度均为O(logn),有着近乎替代平衡树的本领.而且最重要的一点,就是它的编程复杂度较同类

Trie树学习2

数组实现的Trie树 字符容量有限,可以使用链表实现更为大容量的Trie #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <vector> #include <map> #include <set> #include <algorithm> #include <cstdlib> #

trie树(字典树)

1. trie树,又名字典树,顾名思义,它是可以用来作字符串查找的数据结构,它的查找效率比散列表还要高. trie树的建树: 比如有字符串"ab" ,"adb","adc"   可以建立字典树如图: 树的根节点head不存储信息,它有26个next指针,分别对应着字符a,b,c等.插入字符串ab时,next['a'-'a']即next[0]为空,这是申请一个结点放在next[0]的位置,插入字符串db时,next['d'-'a']即next[3]

Trie树

Trie树,即字典树或单词查找树,主要用于大量字符串的检索.去重.排序等操作. 主要原理就是利用字符串的公共前缀建立一棵多叉树,牺牲空间换取时间. 1 //Trie树 2 #include <iostream> 3 #include <string> 4 using std::cin; 5 using std::cout; 6 using std::endl; 7 using std::string; 8 9 const int SIZE = 26; 10 const char B

bzoj4103异或运算 可持久化trie树

要去清华冬令营了,没找到2016年的题,就先坐一坐15年的. 因为n很小,就按照b串建可持久化trie树,a串暴力枚举. 其他的直接看代码. #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; inline int read() { int x=0,f=1,ch=getchar(); while(ch<'0'||ch

hihoCoder 1014 Trie树

#1014 : Trie树 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一本词典,于是小Hi就向小Ho提出了那个经典的问题:“小Ho,你能不能对于每一个我给出的字符串,都在这个词典里面找到以这个字符串开头的所有单词呢?” 身经百战的小Ho答道:“怎么会不能呢!你每给我一个字符串,我就依次遍历词典里的所有单词,检查你给我的字

HDU 1251 Trie树模板题

1.HDU 1251 统计难题  Trie树模板题,或者map 2.总结:用C++过了,G++就爆内存.. 题意:查找给定前缀的单词数量. #include<iostream> #include<cstring> #include<cmath> #include<queue> #include<algorithm> #include<cstdio> #define max(a,b) a>b?a:b #define F(i,a,b