原题:http://acm.hdu.edu.cn/showproblem.php?pid=1671
题意:
给出一些号码,如果其中一个号码是另一个的前缀,则输出NO;
思路:
插入每个号码时,内部数字val = 0,最后一个数字val = 1;
#include<stdio.h>
#include<string.h>
#define MAX 26
const int maxnode = 4000*100+100;
const int sigma_size = 10;
struct Trie
{
int ch[maxnode][sigma_size];
int val[maxnode];
int sz;
void init()
{
sz = 1;
memset(val, -1, sizeof val);
memset(ch[0], 0, sizeof ch[0]);
}
bool insert(char s[])
{
int u = 0, n = strlen(s);
for(int i = 0;i<n;i++)
{
int id = s[i]-'0';
if(ch[u][id] == 0)
{
ch[u][id] = sz;
memset(ch[sz], 0, sizeof ch[sz]);
val[sz++] = 0;
}
u = ch[u][id];
if(val[u] == 1) //字典树中已经插入的号码是当前号码的前缀
return false;
}
val[u] = 1;
for(int i = 0;i<sigma_size;i++) //当前号码是字典树中已存在号码的前缀
{
if(ch[u][i])
return false;
}
return true;
}
}trie;
int main()
{
int cas;
scanf("%d", &cas);
while(cas--)
{
int n;
trie.init();
scanf("%d", &n);
bool flag = true;
for(int i = 1;i<=n;i++)
{
char str[10];
scanf("%s", str);
if(flag)
flag = trie.insert(str);
}
if(!flag)
printf("NO\n");
else
printf("YES\n");
}
return 0;
}