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;
}
原文地址:https://www.cnblogs.com/nanke/p/2044718.html