电话薄
Time Limit:10000MS Memory Limit:65536K
Case Time Limit:1000MS
Description
何老板的手机很先进,当要拨打一个号码时,你需敲出该号码的前面几个数字,手机就会自动找出以该数字为前缀的所有号码。
比如下列电话薄:
TOM:1388
JIM:13885599999
LEE:13812345678
TEC:0236588888
如果何老板敲了138三个数字,手机屏幕上就会显示TOM、JIM和LEE的名字。很是方便呀!
但是何老板发现有不好的地方就是比如他想拨打JIM的号码,当他在手机上敲了1388这四个数字,没等何老板敲完其它数字,手机就会自动拨打TOM的号码,这让何老板很是烦恼。也就是说一旦手机发现你当前敲出的数字与电话薄中的某个号码匹配了,它就会自动拨打该号码。
于是何老板想知道,他的电话薄中,也就是是否存在一个号码是其它号码的前缀的情况。
Input
第一行,一个整数t,表示有t组测试数据1 ≤ t ≤ 40
对于每组测试数据:
第一行一个整数n(1 ≤ n ≤ 10000),表示电话薄中有n个号码
接下来n行,每行一个数字,表示一个电话号码,每个电话号码的长度不超过10,并且是唯一的。
Output
每组测试数据输出一行,如果有有号码是其它号码的前缀,输出"NO"否则输出"YES"
Sample Input
2
4
1388
13885599999
13812345678
0236588888
5
113
12340
123440
12345
98346
Sample Output
NO
YES
Source
改编自Nordic 2007 poj3630
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 20009
struct node{bool used, haveson;int next[11];}trie[maxn*10];
int tot=1;
void _solve()
{
int n, i, p, len;
bool flag=1;
char phone[20];
scanf("%d", &n);
while(n--)
{
scanf("%s", phone);
p=1;
len=strlen(phone);
for(int i=0; i<len; i++)
{
int t=phone[i]-'0';
trie[p].haveson=true;
if(trie[p].next[t]==0)
{
tot++;
trie[p].next[t]=tot;
p=trie[p].next[t];
}
else
{
p=trie[p].next[t];
if(trie[p].used) flag=0;
}
}
trie[p].used=true;
if(trie[p].haveson)
{
flag=0;
}
}
if(flag) printf("YES");
else printf("NO");
putchar('\n');
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
_solve();
for(int i=1; i<=tot; i++)
{
trie[i].haveson=trie[i].used=0;
for(int j=0; j<11; j++) trie[i].next[j]=0;
}
tot=1;
}
return 0;
}