hihocoder1618 单词接龙
#1618 : 单词接龙
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
给定一个单词字典和一个起始字母。小Hi需要从起始字母开始,每次再加上一个字母,生成长度为2、3、4……的单词;并且保证每个生成的单词都在字典中。
求能生成的最长单词的长度。
例如字典是{h, ho, hi, iho, hiho, hihocoder}, 起始字母是h,那么可以通过h-ho-iho-hiho得到长度为4的单词。
输入
第一行包含一个整数N和一个小写字母c。
第二行包含N个空格分开的由小写字母组成的单词单词。保证起始字母c在字典中。
对于30%的数据,1 ≤ N ≤ 100,单词长度之和 ≤ 10000
对于100%的数据,1 ≤ N ≤ 10000,单词长度之和 ≤ 1000000
输出
能生成的最长单词的长度
- 样例输入
-
6 h hihocoder h ho hi hiho iho
- 样例输出
-
4
找错ing
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
const int maxn=2000010;
int Next[maxn][26],End[maxn],fail[maxn],h[maxn],red[maxn];
int cnt,root=1,ans;
int q[10000000],tail,head;
char c[maxn] ,S;
void _init()
{
ans=0;cnt=1;fail[root]=-1;
head=tail=0;End[root]=0;
for(int i=0;i<26;i++) Next[root][i]=0;
}
void _insert(char s[])
{
int L=strlen(s);
int Now=root;
for(int i=0;i<L;i++){
if(!Next[Now][s[i]-'a']) {
Next[Now][s[i]-'a']=++cnt;
fail[cnt]=0;End[cnt]=0;
for(int i=0;i<26;i++) Next[cnt][i]=0;
h[cnt]=h[Now]+1;
}
Now=Next[Now][s[i]-'a'];
}
End[Now]=1;
}
void _build()
{
q[++head]=root;
while(tail<head){
int Now=q[++tail];
if(red[fail[Now]]&&End[Now]&&h[fail[Now]]+1==h[Now]){
if(h[Now]>ans) ans=h[Now];
red[Now]=1;
}
for(int i=0;i<26;i++){
if(red[Now]&&End[Next[Now][i]]) {
red[Next[Now][i]]=1;
ans=max(ans,h[Next[Now][i]]);
}
if(Next[Now][i]){
if(Now==root) fail[Next[Now][i]]=root;
else{
int p=fail[Now];
while(p){
if(Next[p][i]){
fail[Next[Now][i]]=Next[p][i];
break;
}
p=fail[p];
}
if(!p) {
fail[Next[Now][i]]=root;
}
}
q[++head]=Next[Now][i];
}
}
}
}
int main()
{
char s[maxn];
int n,i;
_init();
scanf("%d",&n);
cin>>S;
for(i=1;i<=n;i++){
scanf("%s",s);
_insert(s);
}
red[Next[root][S-'a']]=1;
ans=1;
_build();
printf("%d\n",ans);
return 0;
}
It is your time to fight!