hdu1671 字典树

来源:互联网 发布:html标签保存到数据库 编辑:程序博客网 时间:2024/05/17 04:36

Phone List

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


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
 
校内比赛时做了一道字典树的题目,当时因为数据太水,我们暴力求解ac了,后来学习了字典树,这是ac的第三道字典树题目了,格式几乎都一样
下面上代码

#include <stdio.h>#include <string.h>#include <stdlib.h>typedef struct ac{    int v;    struct ac *child[11];  //类似与链表的构造}tree;tree *root;int flag;void add(char *s){    int i,j,l=strlen(s);    tree *a=root,*b;    for(i=0;i<l;i++)    {        int k=s[i]-'0';        if(a->child[k]!=NULL)//一个数字一个数字查找,如果发现该数字后面的节点不为空,        {            a=a->child[k];//将a的指针指向(下一层节点)该数字应占用的地址            if(a->v==1)//如果这个节点的 v(标记变量)为1,说明,之前有一个标记了的数串x,最后一个数在这个节点, 所以x为root的子串(x<=root)            {                flag=1;                break;            }        }        else//如果为空,        {            b=(tree*)malloc(sizeof(tree));// 为b申请动态内存            a->child[k]=b;//将a的下一层节点k位置 指向b,即a->child[k]!=NULL (不为空了)  ;            for(j=0;j<10;j++)                b->child[j]=NULL;//将b之后下一层的节点置为空;            a=b;//a指向b的地址        }    }    a->v=1;               // 将 该数串最后一个节点的 标记变量置为1;    for(int i=0;i<10;i++)    {        if(a->child[i]!=NULL)//检查  下一层,, 如果发现有指针不为空(有指向) 则标记flag;        {            flag=1;            return ;        }    }}void clear(tree* a){    if(a==NULL)                      //释放内存        return ;    else    {        for(int i=0;i<10;i++)        {            clear(a->child[i]);        }    }    free(a);}int main(){    int t;    scanf("%d",&t);    char s[10005];    while(t--)    {        root=(tree*)malloc(sizeof(tree));//申请内存        for(int i=0;i<10;i++)            root->child[i]=NULL;        flag=0;//                //初始化        int n;        scanf("%d",&n);       // memset(s)        for(int i=0;i<n;i++)        {            scanf("%s",s);            add(s);        }        if(flag)            printf("NO\n");        else            printf("YES\n");        clear(root);    }}


0 0
原创粉丝点击