思路:把所有单词插入到Trie树中,ans=2*树的节点数-最长的队名的长度(除了最长的队名,其它队名都要打一次删除一次)+n(把n个队名打印出来)。
其实找到规律后Trie树也是多余的,大家可以参考下kuangbin大神的blog:http://www.cnblogs.com/kuangbin/archive/2011/08/08/2130824.html
自己的代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <iostream>
#define MAXN 26
using namespace std;
typedef struct Trie
{
int next[MAXN];
int cnt;
};
Trie f[500000];
int tot;
void TrieInit()
{
int i;
tot=MAXN;
memset(f,0,sizeof(f));
for(i=0;i<MAXN;i++) f[0].next[i]=i+1;
}
void Insert(string s)
{
int i,j,k,l;
l=s.length();
k=0;
for(i=0;i<l;i++)
{
if(f[k].next[s[i]-'a']!=0)
{
k=f[k].next[s[i]-'a'];
f[k].cnt++;
}
else
{
tot++;
f[k].next[s[i]-'a']=tot;
k=tot;
f[k].cnt++;
}
}
}
void work(int n)
{
int i,j,k,t,m,ans;
string str;
TrieInit();
m=0;
for(i=0;i<n;i++)
{
cin>>str;
if(str.length()>m) m=str.length();
Insert(str);
}
ans=0;
for(i=0;i<=tot;i++) ans+=(f[i].cnt>0);
ans=(ans<<1)+n-m;
printf("%d\n",ans);
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
work(n);
return 0;
}