先让我扯点别的(好像一直都是这样啊……)
昨天没做题,忏悔一个。现在来交得这题是前天做(抄)完第一道字典树太兴奋了,顺道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 |
还有这次一定要写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;
这样思维可能更清晰点。那天纠结的我……
话说每天都应该做题啊。不然会遭报应的……今天又被队长抛弃了……你妹的背个毛线英语课文啊……