hdu 5.2.2 Phone List

2 篇文章 0 订阅

先让我扯点别的(好像一直都是这样啊……)

昨天没做题,忏悔一个。现在来交得这题是前天做(抄)完第一道字典树太兴奋了,顺道ko掉得。有点小错,超空间啊超时什么的,改改倒还简单。第一次成功改了一道题,虽然中间各种2b错,但是,看到accept时还是小兴奋了下。

至于为啥昨天没做题……因为晚上很困,然后又被拉着看电影,一个讲爱情的渣片,看的我各种中枪,各种代入,而且我代入的是男主- -。。把某人代入女主了。。。。可是真的很像啊卧槽!尤其是那段男主问女主我们现在算啥关系,女主眨巴着眼睛说不知道,然后吧唧靠在男主肩上然后就这么不了了之木有然后了!毛啊!女主脑子进屎了吧!

唉……

Phone List

Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 47 Accepted Submission(s): 26
 
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
 

简单的字典树。每次insert时判断:1.该位置第一次有这个字母。判断下个字符是否就是结束,是的话prefix=1。2.该位置已经有过这个字母了。2.1判断之前是否有字符串在这个字母处结束。有的话不符合(说明那个字符串是现在字符串的子串)2.2判断下个字符是否就结束了,是的话就不符合(说明现在插入的字符串是之前字符串的子串)。

还有这次一定要写delete了。不然超内存。还要在判断出不符合以后就插面小旗,以后的输入就只是象征性的了。不然超时。

代码很乱懒得改了。可以看到我找错误时已经接近癫狂了……

#include <iostream>
#include <cstring>
#include <string>
#include<cstdlib>
using namespace std;
#define MAX 10
int flag;
struct trie
{
       int prefix;//how many words start from this 
       trie *next[MAX];//26 branch
};

void insert(trie *root,char *s)
{
     int i;
     trie *p=root;
     while(*s!='\0')
     {
         
         if(p->next[*s-'0']==NULL)//no one start from this 
         {
         
             trie *temp=new trie;//son tree
             for(i=0;i<MAX;i++)
             {
                 temp->next[i]=NULL;//initiate
             }
             temp->prefix=0;//there is one word start from this now
             
             if(*(s+1)=='\0')
                 p->prefix=1;
             p->next[*s-'0']=temp;
             
             p=p->next[*s-'0'];
             
             
             
                 
         }
         else
         {
             if(p->prefix==1)
             {flag=1;break;}
            
             p=p->next[*s-'0'];//one more word start from this
             
             if(*(s+1)=='\0')//well
             {flag=1;break;}
         }
         s++;//next character
     }
}
void del(trie *root){
     for(int i = 0; i < MAX; ++i)  
        if(root->next[i] != NULL)  
            del(root->next[i]);  
    delete(root);  

     }

int main()
{
    int i;
    int cas;
    
    cin>>cas;
    while(cas--)
    {
    int n;
    cin>>n;
    flag=0;
    char s[12];
    trie *root= new trie;
    for(i=0;i<MAX;i++)
    {
        root->next[i]=NULL;
    }
    root->prefix=0;
    while(n&&!flag)
    {
            cin>>s;
          // gets(s);
        //   cout<<"n"<<n<<endl;
            insert(root,s);
            n--;
    }
    //cout<<"what a "<<endl;
    while(n)
    {
    //gets(s);
    cin>>s;
    n--;
    }
   // cout<<"fucking day"<<endl;
    
    if(flag==1)
    cout<<"NO"<<endl;
    else
    cout<<"YES"<<endl;
     del( root);
    }
   
  system("pause");
    return 0;
}
    
    
    

因为这是直接拿之前的字典树改的,思维有点被框住了。后来看了别人的题解,发现可以把两种情况(是别人的后缀和别人是当前串的后缀)分开写。在两者中间记录这个串结束的小旗。代码如下:

for(int i = 0; i < len; ++i)  //别的电话是否是该电话的后缀
    {  
        temp = str[i] - 48;  
        if(head->tire[temp] == NULL)  
            head->tire[temp] = &Head[++count]; //字母无出现,则赋予空间  
        head = head->tire[temp];  
        if(head->num) //该电话是否含有其他电话  
            return false;  
    }  
    head->num = 1;  //记录该字串在此处结束。
    for(int i = 0; i < 10; ++i) //该电话是否是其他电话的前缀  
        if(head->tire[i] != NULL)  
            return false;  
这样思维可能更清晰点。那天纠结的我……

话说每天都应该做题啊。不然会遭报应的……今天又被队长抛弃了……你妹的背个毛线英语课文啊……


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值