https://www.patest.cn/contests/pat-a-practise/1040
参考了:
https://segmentfault.com/a/1190000003914228
http://blog.youkuaiyun.com/jtjy568805874/article/details/50856440
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1002;
char s[maxn];
char S[maxn * 2];
int RL[maxn * 2];
int manacher(char s[]) {
int n = strlen(s);
S[n + n + 2] = 0, S[0] = 2; //这里S[2n+2] 是扩充串的结尾的'\0', S[0] 是哨兵,与任何一个字符都不同,介绍后面的判断
for (int i = 0; s[i] ; i++)
{
S[i + i + 1] = S[i + i + 3] = '1'; //填充字符,不与s[] 中的任何字符相同
S[i + i + 2] = s[i];
}
int maxright = 0, pos = 0, maxlen = 0;
for (int i = 1; S[i] ; i++)
{
/*
RL[2*pos-i] i关于pos相对的回文半径,以i为中心的回文半径至少是这个,
如果maxrihgt 离i足够远;否则半径只能到maxright-i
*/
if (i < maxright) RL[i] = min(RL[2 * pos - i], maxright - i);
while (S[i + RL[i]] == S[i - RL[i]]) RL[i]++;
if (i + RL[i] > maxright) {
maxright = i + RL[i];
pos = i;
}
maxlen = max(maxlen, RL[i] - 1);
}
return maxlen;
}
int main()
{
gets(s);
printf("%d\n", manacher(s));
return 0;
}