这道题用到的是manacher算法,是一种用来求回文子串的复杂度为O(n)的算法,第一次接触发现这个方法真是,,,太神奇了,在原来的字符串中间插上‘#’或者其他不会出现的字符,这样就解决了奇偶的问题。利用之前已经记录下来的最大回文半径,可以将复杂度降低。
#include<stdio.h>
#include<string.h>
char a[1000010],b[2000010];
int p[2000010];//用来存放最大回文半径
int main()
{
int id,mx,x,i,temp,cas=1;
while(scanf("%s",a)!=EOF)
{
if(strcmp(a,"END")==0) break;
x=strlen(a);
for(i=1;i<=2*x-1;i++)//中间插入'?'
{
if(i%2==1)
b[i]=a[i/2];
else b[i]='?';
}
p[0]=0;
id=0;
int ans=0;
for(i=1;i<=2*x-1;i++)
{
mx=p[id]+id-1;//记录所能达到的最大长度
if(mx>i) //若i在这个长度内
{
if(mx-i+1>p[2*id-i]) p[i]=p[2*id-i]; //如果i到最大长度的距离大于对称点的回文半径,直接赋值
else //否则进行拓展判断
{
p[i]=mx-i+1;
while( (i-p[i]>0)&&(i + p[i]<=2*x-1)&&b[ i + p[i] ]==b[ i- p[i] ])
{
p[i]++;
}
id=i;
}
}
else //不在长度内
{
p[i]=1;
while( (i-p[i]>0)&&(i+p[i]<=2*x-1)&& b[ i-p[i] ]==b[ i+p[i] ]) p[i]++;
id=i;
}
if(b[i]=='?')
{
temp=p[i]/2*2;
}
else temp=(p[i]-1)/2*2+1;
if(temp>ans)
{
ans=temp;
}
}
printf("Case %d: %d\n",cas++,ans);
}
return 0;
}