HDU1671-Phone List

Phone List

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


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
 
思路1:把所有输入的关键字都存起来,把某个关键字的结尾都存储一个单词结尾标志,然后再一个个查询单词,如果查到某个结尾并不是最后一个结点,则说明有前缀发生.
 
 
思路2:果字符串X=X1X2....Xn是字符串Y=Y1Y2....Ym的前缀,有在插入的时候有两种情况:
X在Y之前插入,X在Y之后插入。
(1)如果Xn在Yn之前插入,那么在插入Yn的时候必然经过Xn的路径,此时可以根据判断在这条路径上是否已经有结点被标记已经构成完成的字符串序列来判断是否存在Yn的前缀;
(2)如果Xn在Yn之后插入,那么插入的过程中必然不需要新申请空间。
 
PS:做这道题目的时候刚开始想是把所有的字符串先存起来,然后在插入的时候给根节点弄个特殊的标记,然后在一个个查找,如果某个字符串查找到结尾时发现结尾不是根节点,
则有重复前缀发生,然后想了一下,如果是长的先插入,短的后插入的话,根节点会弄错,所以又进行了一下排序,然后就一直超内存了!!!
我想着每次都要申请root节点,多麻烦啊,于是就在大循环外面申请了一个root,结果内存爆超啊,想不明白!
还好最后想明白了,原来每一轮运行,由于之前申请的内存没有释放,所以会有累加,于是把根节点放在了循环里面申请,又在末尾部分写了个释放函数,结果就AC了!
 

第二种思路写的

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct telnumber
{
    struct telnumber *child[10];
    bool isroot;
};
struct telnumber *root;
void initial(struct telnumber *node)
{
    int i;
    for(i=0;i<10;i++)
        node->child[i]=NULL;
    node->isroot=0;
}
void freedom(struct telnumber *p)
{
 int i;
 for(i=0;i<10;i++)
  if(p->child[i]!=NULL) freedom(p->child[i]);
 free(p);
}
bool insert(char *source)
{
    int i,len;
 bool preinsert,postinsert; 
    struct telnumber *curent,*newnode;
 preinsert=postinsert=0;
 len=strlen(source);
 curent=root;
    for(i=0;i<len;i++)
    {
        if(curent->child[source[i]-'0']!=NULL)
        {
            curent=curent->child[source[i]-'0'];
    if(curent->isroot==1) preinsert=1;
        }
        else//如果前缀在后面插入,则没有新节点申请
        {
            newnode=(struct telnumber *)malloc(sizeof(struct telnumber));
            initial(newnode);
            curent->child[source[i]-'0']=newnode;
            curent=newnode;
    postinsert=1;//表示申请过新节点,第二种情况不可能发生了
        }
    }
    curent->isroot=1;
  if(preinsert||!postinsert) return 0;//返回0表示有前缀发生
  else return 1;//无前缀发生
}
int main()
{
    int T,n,i;
  bool flag;
  char table[12];
  scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
   root=(struct telnumber *)malloc(sizeof(struct telnumber));
   initial(root);
        for(i=0,flag=1;i<n;i++)
        {
            scanf("%s",table);
    if(insert(table)==0) flag=0;
        }
        if(flag==1) printf("YES\n");
        else printf("NO\n");
   freedom(root);
    }
    return 0;
}


 
weixin073智慧旅游平台开发微信小程序+ssm后端毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值