hdu1671(字典树)
呵呵,这道题目的话,也不难吧,就是在节点中添加了俩个标志
因为想要一边添加一边判断是否出现过某个串是某个串的前缀,所以需要添加这俩个标志
一个是v,用来表示是否有一个串在该节点结束,这主要是针对前面的串中出现过当前串的前缀;
另一个是f,用来标志当前当一个串结束时,它是否存在下一个节点,主要针对当前串是之前出现过的串的前缀
添加这俩个标志之后,基本没什么问题了,对了,初始化还是很严重的问题,额,因为有一个地方忘记初始化了,结果wa了一次
额,还有一个蛮严重的,就是每一个case之后,要释放空间,不然内存使用过大了,虽然大牛说过,但我还是固执的提交了一次,悲剧
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct node
{
node *next[10];
int v;
int f;
}*tree,t;
tree root;
int flag;
void insert(char *str)
{
tree p=root,newnode;
for(;*str!='\0';str++)
{
if(p->next[*str-'0']!=NULL)
{
p->f=1;
p=p->next[*str-'0'];
if(p->v==-1)//前面的串中出现过当前串的前缀
flag=1;
}
else
{
newnode=(tree)malloc(sizeof(t));
for(int i=0;i<=9;i++)
newnode->next[i]=NULL;
newnode->v=0;
newnode->f=0;
p->f=1;
p->next[*str-'0']=newnode;
p=newnode;
}
}
p->v=-1;
if(p->f)//当前串是之前出现过的串的前缀
{
flag=1;
}
}
int deal(node* T)//释放内存空间
{
int i;
for(i=0;i<=9;i++)
{
if(T->next[i]!=NULL)
deal(T->next[i]);
}
free(T);
return 0;
}
int main()
{
int m,n,num;
char str[15];
scanf("%d",&m);
while(m--)
{
flag=0;
root=(tree)malloc(sizeof(t));
for(int i=0;i<=9;i++)
root->next[i]=NULL;
root->v=0;
root->f=0;
scanf("%d",&n);getchar();
while(n--)
{
gets(str);
if(flag)//算是优化吧,可是 还是很慢呀,差距,差距啊
continue;
insert(str);
//puts(str);
}
if(!flag)
printf("YES\n");
else printf("NO\n");
deal(root);
}
return 0;
}

浙公网安备 33010602011771号