题目链接:http://poj.org/problem?id=3974
题目大意:给定字符串S,求出最长的回文字串长度
用manacher算法可以在O(n)的复杂度求出回文字串长度
manacher算法详解:http://blog.youkuaiyun.com/xingyeyongheng/article/details/9310555
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
#define N 1000100
int p[N*2+1];//以i为中心的(包含i这个字符)回文串半径长
char s[N*2+1];
void init(char *s,int len){
int i;
//在每个相邻的字符之间插入一个分隔符,把奇数长度回文串与偶数长度回文串统一考虑
for(i=len;i>=0;--i){
s[i+i+2]=s[i];
s[i+i+1]='#';
}
//插入了len+1个'#',最终的s长度是1~len+len+1即2*len+1,首尾s[0]和s[2*len+2]要插入不同的字符
s[0]='*';//s[0]='*',s[len+len+2]='\0',防止在while时p[i]越界
//aba->*#a#b#a#\0
}
int manacher(char *s,int len){
int i;
int maxlen=0,id=0;
for(i=1;i<2*len+1;++i){
if(p[id]+id>i)
p[i]=min(p[id-(i-id)],id+p[id]-i);
else
p[i]=1;
while(s[i-p[i]]==s[i+p[i]]) p[i]++;
if(id+p[id]<i+p[i])
id=i;
maxlen=max(maxlen,p[i]);
}
return maxlen-1;
//aba->*#a#b#a#\0
//maxlen=p[4]=4;
}
int main(){
int cas=1;
while(scanf("%s",&s)!=EOF&&s[0]!='E'){
int len=strlen(s);
int ans=0;
init(s,len);
ans=manacher(s,len);
printf("Case %d: %d\n",cas++,ans);
}
return 0;
}