Problem Description
给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.
回文就是正反读都是一样的字符串,如aba, abba等
回文就是正反读都是一样的字符串,如aba, abba等
Input
输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S
两组case之间由空行隔开(该空行不用处理)
字符串长度len <= 110000
两组case之间由空行隔开(该空行不用处理)
字符串长度len <= 110000
Output
每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度.
Sample Input
aaaa abab
Sample Output
4 3
题解:
当初也不知道有这种算法的。 叫做manacher。
这种算法具体解释可以看这里
代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int N=111111;
char a[N],s[N<<1];
int p[N<<1];
int s1,s2;
int main(){
int i,Maxid,MaxL,j,id,n;
while(scanf("%s",a+1)!=EOF){
s[0]='?';
for(i=1;a[i]!='\0';i++){
s[i<<1]=a[i];
s[i<<1|1]='#';
}s[1]='#';
n=(i<<1),s[n]=0;
Maxid=MaxL=0;
j=i<<1;
for(i=1;i<n;i++){
if(Maxid>i){
p[i]=min(p[id*2-i],Maxid-i);
}else{
p[i]=1;
}
while(s[ i-p[i] ]==s[ i+p[i] ]){
p[i]++;
}
if(p[i]+i>Maxid){
Maxid=p[i]+i;
id=i;
}
if(p[i]>MaxL)
MaxL=p[i];
}
printf("%d\n",(MaxL*2-1)/2);
}
return 0;
}