FJUT ACM 1240 ( ̄y▽ ̄)~ 智能手机II

( ̄y▽ ̄)~ 智能手机II

TimeLimit: 3000/1000 MS (Java/Others)  MemoryLimit: 32768/32768 K (Java/Others)
64-bit integer IO format:%I64d
Problem Description
在我们的手机通讯录中,我们可以通过输入手机号码时,搜索都联系人。如果当我们输入的手机号码正好也是另外一个手机号码的部分前缀时,同样会显示,前缀为这个手机号码的人的信息。只有当你输入的号码是唯一的,也就是输入的号码不是其他号码的前缀,,才会唯一的显示一个人的信息。 
比如: 
1. LhBoy 911 
2. bobo 10086 
3. hzz 10010 
当你输入其中任何一个人的号码时,都只会唯一的显示一个人的信息的、 
如果这个通讯录多增加一组:4. Orz 1001011 ,则,当你输入10010的时候,所查找到的联系人有hzz和Orz。 
现在问题来了,给你一个通讯录,问你在通过手机号码查询时,所查询出来的联系人的信息是否唯一,唯一的话输出YES,否则输出NO。 
*内存超限的话,就尝试着释放内存把( ̄y▽ ̄)~~
Input
第一行输入一个整数T,表示有T(1 <= t <= 40)组测试案例。 
每一组测试案例先输入一个整数N( 1 <= n <= 10000),表示通讯录有N条信息。 
接下来有N行,每一行表示各个联系人的电话号码,每一个电话号码最多10位数。
Output
For each test case, output “YES” if the list is consistent, or “NO” otherwise.
SampleInput
2
3
811
87625999
81125426
5
113
12340
123440
10086
98346
SampleOutput
NO
YES
【思路】:看到这个的时候,我的思路就是字典树,先根据输入的数值建立一棵字典树,并且再每个电话结束的节点,标记为1;
然后我写了个dfs()向下寻找,如果找到节点值为1的,再向下寻找看是否为NULL;为空就代表没有前缀,不为空,就代表有重复;
贴上代码:
#include <bits/stdc++.h>
int flag;
typedef struct Tire
{
    int num;
    struct Tire *next[15];
} tire;
tire *creattire()
{
    tire *p;
    p=(tire *)malloc(sizeof(tire));
    p->num=0;
    for(int i=0; i<10; i++)
        p->next[i]=NULL;
    return p;
}
void addtire(char word[],tire *root)
{
    int ans;
    int len=strlen(word);
    for(int i=0; i<len; i++)
    {
        ans=word[i]-'0';
        if(root->next[ans]==NULL)
        {
            tire *q;
            q=creattire();
            root->next[ans]=q;
            root=root->next[ans];
        }
        else
        {
            root=root->next[ans];
        }
        if(i==len-1)
        {
            root->num=1;
        }
    }
}
void deletetire(tire *root)
{
    if(root==NULL)
        return ;
    for(int i=0; i<10; i++)
    {
        if(root->next[i]!=NULL)
        {
            deletetire(root->next[i]);
        }
    }
    free(root);
}
void dfs(tire *root)
{
    if(root->num==1)
    {
        int flags=0;
        for(int i=0; i<10; i++)
        {
            if(root->next[i]!=NULL)
            {
                flags=1;
                break;
            }
        }
        if(flags==1)
        {
            flag++;
            return ;
        }
    }
    for(int i=0; i<10; i++)
    {
        if(root->next[i]!=NULL)
        {
            dfs(root->next[i]);
        }
    }
}
int main()
{
    int t;
    tire *root;
    char word[15];
    while(~scanf("%d",&t))
    {
        while(t--)
        {
            int n;
            flag=0;
            root=creattire();
            scanf("%d",&n);
            flag=0;
            memset(word,0,sizeof(word));
            for(int i=0; i<n; i++)
            {
                scanf("%s",&word);
                addtire(word,root);
            }
            dfs(root);
            if(flag!=0)
                printf("NO\n");
            else
                printf("YES\n");
            deletetire(root);
        }
    }
    return 0;
}

 

posted @ 2018-03-16 13:54  moxin0509  阅读(172)  评论(0编辑  收藏  举报