hdu3460(字典树)

http://acm.hdu.edu.cn/showproblem.php?pid=3460

题意:一开始没有明白题意,看了好久,才明白,原来它是将一个单词打印出来后再在打印机里面删除字母,也就是说,如果单词前缀相同,则只需删除单词不相同的部分,再插入下一个单词不相同的部分。这样的话,可以用字典树,要是单词前缀相同,则在字典树上只有一个结点,那么,要是将最长的那个单词也删除了,则是对字典树上的结点插入一次再删除一次,还要输出n次,也就是2*numnode+n;但是最长的那个单词len不需要删除,则是2*numnode+n-len;

#include<iostream>
#include<cstring>
using namespace std;
typedef struct tree
{
	int num;
	tree *next[26];
}tree;
tree *root;
int count;
void creat(char str[])
{
	int len=strlen(str);
	tree *p=root,*q;
	for(int i=0;i<len;i++)
	{
		int x=str[i]-'a';
		if(p->next[x])
		{
			p->next[x]->num++;
			p=p->next[x];
		}
		else
		{
			q=(tree *)malloc(sizeof(tree));
			q->num=1;
			for(int j=0;j<26;j++)
				q->next[j]=NULL;
			p->next[x]=q;
			p=q;
			count++;
		}
	}
}
void del(tree *p)
{
	for(int i=0;i<26;i++)
	{
		if(p->next[i])
			del(p->next[i]);
	}
	free(p);
}
int main()
{
	int n;
	while(scanf("%d",&n)>0)
	{
		root=(tree *)malloc(sizeof(tree));
		for(int j=0;j<26;j++)
			root->next[j]=NULL;
		root->num=0;
		char s[50];
		int i,max=0,len;
		count=0;
		for(i=0;i<n;i++)
		{
			scanf("%s",s);
			creat(s);
			len=strlen(s);
			if(len>max)
				max=len;
		}
		printf("%d\n",2*count+n-max);
		del(root);
	}
	return 0;
}

 

 

posted @ 2012-12-24 15:57  紫忆  阅读(422)  评论(0编辑  收藏  举报