Phone List

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
 
Source

解题思路:

推断输入的串中是否存在某个串是另外串的前缀。

建立字典树,关键是设立某个串结尾的标志,即在哪个字母结尾。

要推断是否存在前缀要考虑两种情况。一是当前输入的串是否是曾经输入的串的前缀,而是曾经输入的串是否是当前输入的串的前缀。前一种情况在查找该串时,会从第一个字母查找到最后一个字母,中间不返回不论什么值,说明当前的串是曾经的前缀,后一种情况。当在查找当前串的时候遇到曾经串结束的标志。则说明曾经串是当前串的前缀。

代码中结束的标志为保存串中最后一个字母的那个节点的cnt值为-1.

如图:

代码:

#include <iostream>
#include <malloc.h>
#include <algorithm>
#include <string.h>
#include <stdio.h>
using namespace std;
const int maxn=10;
bool ok;
char str[12];
int t,n; struct Trie
{
int cnt;
Trie *next[maxn];
}; Trie *root; void CreateTrie(char *str)
{
int len=strlen(str);
Trie*p=root,*q;
for(int i=0;i<len;i++)
{
int id = str[i]-'0';
if(p->next[id] == NULL)
{
q = (Trie *)malloc(sizeof(Trie));
q->cnt = 1;
for(int j=0; j<maxn; ++j)
q->next[j] = NULL;
p->next[id] = q;
p = p->next[id];
}
else
{
p = p->next[id];
}
}
p->cnt=-1;//串末尾的标志
} int findTrie(char *str)
{
int len=strlen(str);
Trie *p=root;
for(int i=0;i<len;i++)
{
int id=str[i]-'0';
if(p->next[id]==NULL)
return 0;//没有建过树
if(p->next[id]->cnt==-1)
return -1;//曾经串是当前串的前缀
p=p->next[id];
}
return -1;//当前串是曾经串的前缀
} void release(Trie *root)//释放空间
{
for(int i=0;i<maxn;i++)
{
if(root->next[i])
release(root->next[i]);
}
free(root);
}
int main()
{
scanf("%d",&t);
while(t--)
{
ok=1;
root=(Trie*)malloc(sizeof(Trie));//root为指针类型,须要申请空间
for(int i=0; i<10; ++i)
root->next[i] = NULL;
scanf("%d",&n);
while(n--)
{
scanf("%s",str);
if(findTrie(str)==-1)
ok=0;//有前缀
if(!ok)
continue;//有前缀,后面的就不用建树了
CreateTrie(str);
}
if(ok)
printf("YES\n");
else
printf("NO\n");
release(root);
}
return 0;
}

[ACM] hdu 1671 Phone List (字典树)的更多相关文章

  1. hdu 1671 Phone List 字典树

    // hdu 1671 Phone List 字典树 // // 题目大意: // // 有一些电话号码的字符串长度最多是10,问是否存在字符串是其它字符串的前缀 // // // 解题思路: // ...

  2. hdu 1671 Phone List 字典树模板

    Given a list of phone numbers, determine if it is consistent in the sense that no number is the pref ...

  3. ACM学习历程—HDU 4287 Intelligent IME(字典树 || map)

    Description We all use cell phone today. And we must be familiar with the intelligent English input ...

  4. hdu 1251 统计难题 (字典树入门题)

    /******************************************************* 题目: 统计难题 (hdu 1251) 链接: http://acm.hdu.edu. ...

  5. HDU 5536 Chip Factory 字典树

    Chip Factory Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid= ...

  6. HDU 1298 T9(字典树+dfs)

    http://acm.hdu.edu.cn/showproblem.php?pid=1298 题意:模拟手机9键,给出每个单词的使用频率.现在给出按键的顺序,问每次按键后首字是什么(也就是要概率最大的 ...

  7. hdu 1251 统计难题(字典树)

    统计难题 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131070/65535 K (Java/Others) Total Subm ...

  8. HDU 1298 T9【字典树增加||查询】

    任意门:http://acm.hdu.edu.cn/showproblem.php?pid=1298 T9 Time Limit: 2000/1000 MS (Java/Others)    Memo ...

  9. hdu 1251 统计难题 (字典树(Trie)<PS:C++提交不得爆内存>)

    统计难题Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131070/65535 K (Java/Others)Total Submis ...

随机推荐

  1. 用最简单的例子理解策略模式(Strategy Pattern)

    当一个动作有多种实现方法,在实际使用时,需要根据不同情况选择某个方法执行动作,就可以考虑使用策略模式. 把动作抽象成接口,比如把玩球抽象成接口. public interface IBall { vo ...

  2. 转:在两个页面间翻转设置Animation动作的一些总结

    今天碰到两个页面之间翻转的动作设计问题,发现了一些问题,故做个总结,很多都写在注释部分: 1.首先,我们来手动创建两个view以及相应的viewController.是手动,不是用IB (1)刚开始只 ...

  3. android 管理手机短信

    为了看代码方便,一边在网上google资料,一边看Android java 源代码. 偶然发现了一个类MmsSmsDatabaseHelper.java,原来android将所有的短信信息都存入了mm ...

  4. 一款DIY移动电源的性能

    文波很大 就这款产品,质量非常一般后面拿品胜的做个对比

  5. Servlet监听器统计在线人数

    监听器的作用是监听Web容器的有效事件,它由Servlet容器管理,利用Listener接口监听某个执行程序,并根据该程序的需求做出适应的响应. 例1 应用Servlet监听器统计在线人数. (1)创 ...

  6. [7] 金字塔(Pyramid)图形的生成算法

    顶点数据的生成 bool YfBuildPyramidVertices ( Yreal width, Yreal length, Yreal height, YeOriginPose originPo ...

  7. rotate-function

    https://leetcode.com/problems/rotate-function/ public class Solution { public int maxRotateFunction( ...

  8. iOS开发-UITableView常用方法

    UITableView常用来展示数据,类似于Android中的ListView,相对于Android中的ListView而言,UITableView的实现是非常简单,继承UITableViewData ...

  9. App优化 StrictMode 严格模式

    StrictMode简介 StrictMode最常用来捕捉应用程序的主线程,它将报告与线程及虚拟机相关的策略违例.一旦检测到策略违例policy violation,你将获得警告,其包含了一个栈tra ...

  10. operator++()和operator++(int)的区别

    很久以前(八十年代),没有办法区分++和--操作符的前缀与后缀调用.这个问题遭到程序员的报怨,于是C++语言得到了扩展,允许重载increment 和 decrement操作符的两种形式. 然而有一个 ...