HDu 3460(辞書ツリー)
1552 ワード
http://acm.hdu.edu.cn/showproblem.php?pid=3460
最初は意味がわからなくて、長い間見ていて、やっと分かりました.単語を印刷してからプリンタの中でアルファベットを削除します.つまり、単語の接頭辞が同じであれば、単語の異なる部分を削除して、次の単語の異なる部分を挿入するだけです.このように、辞書ツリーを使って、単語の接頭辞が同じであれば、辞書ツリーに1つのノードしかありません.では、最も長い単語も削除すると、辞書ツリーのノードに1回挿入してもう一度削除し、n回出力します.つまり2*numnode+nです.しかし、最も長い単語lenは削除する必要はありません.2*numnode+n-lenです.
最初は意味がわからなくて、長い間見ていて、やっと分かりました.単語を印刷してからプリンタの中でアルファベットを削除します.つまり、単語の接頭辞が同じであれば、単語の異なる部分を削除して、次の単語の異なる部分を挿入するだけです.このように、辞書ツリーを使って、単語の接頭辞が同じであれば、辞書ツリーに1つのノードしかありません.では、最も長い単語も削除すると、辞書ツリーのノードに1回挿入してもう一度削除し、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
",2*count+n-max);
del(root);
}
return 0;
}