poj 4089 Phone List(tire树)

来源:互联网 发布:编程可以做什么 编辑:程序博客网 时间:2024/05/27 20:51

poj 4089 Phone List(tire树)
Time Limit: 1000ms Memory Limit: 65536kB

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 dialed 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


Tire树即字典树,用于处理查询大量单词或其前缀的问题。本题正好可以用Tire树这个数据结构解决。只需要用Tire树保存已有的单词并判断是否非法即可。注意一个单词是别人的前缀就必定非法了。
Tire树这个数据结构在《数据结构与算法》中学习到过,但是书里面只描述一下原理,并没有给实现代码。实现Tire树一个细节问题是子结点数目不确定,如何解决这一问题。可行的方案由要么动态分配子结点表(太过于麻烦),要么就用静态左子右兄法储存,我下面的代码采取这一方式。
这学期学了《数据结构与算法》和配套的实习课,感觉对树型数据结构实现越来越得心应手了。


Accepted    6932kB  216ms   1205 B  G++
#include<stdio.h>const int SIZE=10000;const int LEN=10;struct node_type{    int l,r;//leftmost son & right sibling    char value;    bool end;};node_type tire[SIZE*LEN*2+1];int len;bool deal(int node,char* s){    int t=tire[node].l;    if (*s==0)    {        if (tire[node].end || tire[node].l!=-1)            return false;        else        {            tire[node].end=true;            return true;        }    }    while (t!=-1 && tire[t].value!=*s)        t=tire[t].r;    if (t==-1)    {        tire[len].l=-1;        tire[len].r=tire[node].l;        tire[node].l=len;        tire[len].end=false;        tire[len].value=*s;        t=len;        len++;    }    else if (tire[t].end==true)            return false;    return deal(t,s+1);}int main(){    int cases,n;    bool legal;    char str[LEN+1];    scanf("%d\n",&cases);    while (cases--)    {        scanf("%d\n",&n);        legal=true;        len=1;        tire[0].l=tire[0].r=-1;        tire[0].end=false;        //tire[0] is the virtual root         while (n--)        {            scanf("%s\n",&str);            if (legal)                legal=deal(0,str);        }        printf("%s\n",legal?"YES":"NO");    }    return 0; }
0 0
原创粉丝点击