字典树HDU1671

来源:互联网 发布:淘宝店家信用怎么看 编辑:程序博客网 时间:2024/04/30 22:02
#include <stdio.h>

#include <string.h>

#include<stdlib.h>

#define max 10
int c;
struct trie                                //定义树的每一个节点
{
trie *next[max];
bool v;
};
trie *root;
trie memory[120010];          //用于储存每一个新节点,如果每添加一次节点清0一次,容易超时
int build(char *str)                 //建立字典树
{
int len=strlen(str);
trie *p=&memory[0];
for(int i=0;i<len;++i)
{
int id=str[i]-'0';
if(p->next[id]==NULL)
{
p->next[id]=&memory[++c];
p->v=1;                                 //判断是否搜索到树的底端
p=p->next[id];
}
else
{
if(i==len-1)                         //当前号码是某个号码的前缀,直接跳出
return 1;
p=p->next[id];
if(p->v==0)                         //某个号码是当前号码的前缀,直接跳出
return 1;
}
}
p->v=0;                                              //该树枝的末尾标记
return 0;
}
void retrie(trie *p)                                    //清空该字典树,否则容易ML
{
for(int i=0;i<max;i++)
if(p->next[i]!=NULL)
retrie(p->next[i]);
free(p);
}
int main()
{
int t;
int n,i;
int tot;
int flag;
char map[15];
while(scanf("%d",&t)!=-1)
{
while(t--)
{
root=new trie;
root->v=0;
root->num=0;
for(i=0;i<max;++i)
{
root->next[i]=NULL;
}
c=0;
flag=1;
memset(memory,0,sizeof(memory));
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%s",map);
if(flag==0)                        //如果出现了一个前缀,那其余号码均不需处理
continue;
tot=build(map);
if(tot==1)
flag=0;
}
if(flag==1)
printf("YES\n");
else
printf("NO\n");
retrie(root);                            //清空字典树
}
}
return 0;
}
0 0
原创粉丝点击