HDU 1671 Phone List 字典树

来源:互联网 发布:仿猪八戒源码 编辑:程序博客网 时间:2024/05/29 14:55

Phone List

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 9876    Accepted Submission(s): 3365


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
2391197625999911254265113123401234401234598346
 

Sample Output
NOYES
 

Source
2008 “Insigma International Cup” Zhejiang Collegiate Programming Contest - Warm Up(3)
 

Recommend
lcy

//二维数组+动态内存+释放,需要注意指针数组的使用方法//和树完全建完后,怎么释放树//大致题意:多组电话号码,如果存在某组是其他组的前缀则输出NO#include <iostream>#include <string>#include <cstdlib>#include <cstring>#include <cstdio>using namespace std;char *str[10001];typedef struct Node{    int cnt ;    Node *child[11];}Node;void init(Node *root){    int i;    for(i=0;i<11;i++)        root->child[i] = NULL;    root->cnt=0;}void insert(char *s,Node *root)//注意指针数组的传参方式{    Node *current = root;    int i;    for(i=0;i<s[i]!='\0';i++)    {        int index = s[i]-'0';        if(current->child[index] != NULL)        {            current = current->child[index];            (current->cnt)++;        }        else        {            Node *newnode = new Node;            init(newnode);            current->child[index] = newnode;            current = newnode;            current->cnt =1;        }    }}bool find (char *s,Node *root){    Node *current = root;    int i;    /*    for(i=0;s[i]!='\0';i++)    {        int index = s[i]- '0';        if(current->child[index]&¤t->cnt>1)            current = current->child[index];        //实际上下面这种情况不可能存在,但为保险起见,        //没有直接else        //else if(current->child[index]==NULL)          //  return true;        else if(current->cnt=1)            return false;    }    return true;    */    for(i=0;s[i]!='\0';i++)    {        int index = s[i]- '0';        //不必再加上if判断了,必定可以走到末尾,因为他就是树里的串        current = current->child[index];    }    if(current->cnt==1) return false;    return true;}void My_delete(Node *root){    int i;    if(root==NULL)        return ;    else//加不加else均可AC    {        for(i=0;i<11;i++)        {            if(root->child[i])                My_delete(root->child[i]);        }    }    delete root;    return ;}int main(){    int i,j,k,T;    cin>>T;    while(T--)    {        Node *root = new Node;        init(root);//开在局部,希望对减小内存有所帮助        int num;        cin>>num;        memset(str,0,sizeof(str));        i=0;        k = num;        while(num--)        {            //用指针数组的话,必须给他申请空间,否则出现内存不可写            str[i]=(char *)malloc(11*sizeof(char));            cin>>str[i];            //gets(str[i]);            /*            刚开始这用的是gets,上面cin>>num时,            没有吸收掉换行符会被gets吸收,所以输入少于一行时就输出了结果            换位cin以后就不必加上getchar了,因为cin不接受换行符            */            insert(str[i],root);            i++;        }        //上面的num已经变化,所以下面不可再使用num(num=-1) ,看来以后在内部输入还是用for循环吧        for(j=0;j<k;j++)        {            bool flag = find (str[j],root);            if(flag)            {                cout<<"NO"<<endl;                break;            }        }        if(j==k)            cout<<"YES"<<endl;        My_delete(root);    }    return 0;}


0 0