这道题也是Trie树 应用的入门题,题意:问输入的一组电话号码中有没有某一个号码是另一个的前缀。
开始的代码在hdu上AC了,交到poj上却超时了。
后来,看了discuss,发现自己用了new操作,而没有先开辟空间。若用缓存,每次有新节点时直接存放在已开辟的空间内,会节省很多时间。
之后把代码稍改了改,就ac了,188ms~~
题目链接:POJ 3630、 ZOJ 2876 、HDU 1671
#include<stdio.h>
#include <string.h>
const int sonnum=10, base='0';
int nodenum;
struct Trie{
int num;
bool terminal;
struct Trie *son[sonnum];
}trie[100000];
int Insert(Trie *root, char *s)
{
int flag=0;
Trie *temp=root;
while(*s)
{
if(temp->son[*s-base]==NULL)
temp->son[*s-base]=&trie[nodenum++];
else
{
temp->son[*s-base]->num++;
if(temp->son[*s-base]->terminal)//该节点处是其他串的终点
flag=1;
}
temp=temp->son[*s-base];
s++;
}
temp->terminal=true;
if(temp->num>1)flag=1;//该串末节点处已其他串的中间节点
return flag;
}
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
for(int i=0;i<100000;i++)
{
trie[i].num=1;
trie[i].terminal=false;
memset(trie[i].son,NULL,sizeof(trie[i].son));
}
nodenum=0;
Trie *root=&trie[nodenum++];
char a[11];
int p=0;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%s",a);
if(!p&&Insert(root,a))//若已存在前缀,则不需再插入
p=1;
}
if(!p)printf("YES\n");
else printf("NO\n");
}
return 0;
}