题目描述
风之子刚走进他的考场,就……
花花:当当当当~~偶是魅力女皇——花花!!^^(华丽出场,礼炮,鲜花)
风之子:我呕……(杀死人的眼神)快说题目!否则……-_-###
花花:……咦好冷我们现在要解决的是魔族的密码问题(自我陶醉:搞不好魔族里面还会有人用密码给我和菜虫写情书咧,哦活活,当然是给我的比较多拉*^_^*)。魔族现在使用一种新型的密码系统。每一个密码都是一个给定的仅包含小写字母的英文单词表,每个单词至少包含1个字母,至多75个字母。如果在一个由一个词或多个词组成的表中,除了最后一个以外,每个单词都被其后的一个单词所包含,即前一个单词是后一个单词的前缀,则称词表为一个词链。例如下面单词组成了一个词链:
i int integer
但下面的单词不组成词链:
integer intern
现在你要做的就是在一个给定的单词表中取出一些词,组成最长的词链,就是包含单词数最多的词链。将它的单词数统计出来,就得到密码了。
风之子:密码就是最长词链所包括的单词数阿……
花花:活活活,还有,看你长得还不错,给你一个样例吧:
输入输出格式
输入格式:这些文件的格式是,第一行为单词表中的单词数N(1<=N<=2000),下面每一行有一个单词,按字典顺序排列,中间也没有重复的单词咧!!
你要提交的文件中只要在第一行输出密码就行啦^^
输入输出样例
输入样例#1:
5 i int integer intern internet
输出样例#1:
4
本来是想找DP题来刷一刷,结果找到了一道 Trie树,于是顺手A了。。。
附代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define MAXN 200010
using namespace std;
int n,size=1,ans=0;
struct node{
int val,son[26];
node(){
memset(son,0,sizeof(son));
val=0;
}
}a[MAXN];
inline int read(){
int date=0,w=1;char c=0;
while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
return date*w;
}
inline int idx(char c){return c-'a';}
void insert(char *s,int v){
int u=0,ansx=0,l=strlen(s);
for(int i=0;i<l;i++){
int c=idx(s[i]);
if(!a[u].son[c])a[u].son[c]=size++;
u=a[u].son[c];
ansx+=a[u].val;
}
a[u].val+=v;
ans=max(ans,ansx);
}
int main(){
char ch[MAXN];
n=read();
for(int i=1;i<=n;i++){
scanf("%s",ch);
insert(ch,1);
}
printf("%d\n",ans+1);
return 0;
}