链接:http://acm.hdu.edu.cn/showproblem.php?pid=1671
题目的意思可能不好理解:
其实他的意思是:给你号码,如果有出现其中的号码是其他号码的前缀,则NO,否则YES。
用字典树储存号码,然后搜索是否有前缀
很明白的一道模板题了,就不多做解释了。
不过值得一提的是,这道题如果没有写上树的释放函数,肯定错。
其实一般字典树的题目都写上这个函数,是不会有问题的。
AC代码如下:
#include<iostream>
#include<stdio.h>
#include<cstring>
using namespace std;
typedef struct tree
{
int num;
tree *next[11];
tree()
{
num=0;
int i;
for(i=0;i<11;i++)
{
next[i]=NULL;
}
}
}Node;
Node *head;
void UFset()
{
int i;
head=new Node; //头结点
for(i=0;i<11;i++)//26个结点,初始化
{
head->next[i]=NULL;
head->num=0;
}
}
void Tree_insert(char *str)
{
Node *s=head,*t;
int len=strlen(str);
int i;
for(i=0;i<len;i++)
{
int id=str[i]-'0';
if(s->next[id]==NULL)
{
t=new Node;
s->next[id]=t;
}
s=s->next[id];
s->num++;
}
}
int Tree_Find(char *str)
{
int count;
int len=strlen(str);
Node *s=head;
int i;
for(i=0;i<len;i++)
{
int id=str[i]-'0';
if(s->next[id]==NULL)
{
count=0;
return count;
}
else
{
s=s->next[id];
count=s->num;
}
}
return count;
}
void del(Node *head)//!!!释放内存的部分!!!非常重要!!!!
{
Node *s=head;
int i;
for(i=0;i<11;++i)
if(s->next[i]!=NULL)
del(s->next[i]);
free(s);
}
int main()
{
int ncase;
scanf("%d",&ncase);
while(ncase--)
{
int n;
char number[10010][15];
scanf("%d%*c",&n);
int i;
UFset();
for(i=0;i<n;i++)
{
gets(number[i]);
Tree_insert(number[i]);
}
int num=0;
for(i=0;i<n;i++)
{
if(Tree_Find(number[i])>1)
{
num=1;
break;
}
else
num=0;
}
if(num==1)
printf("NO\n");
else
printf("YES\n");
del(head);
}
return 0;
}