方便捡起的水博客
用到的数据:
1.回文半径 . 回文直径 ,并生成回文半径数组 pArr
2.之前扩的所有位置中,所到的 最右回文右边界 R
3.取地更远半径时 中心点在哪? C
情况1:
当前点,没有在 最右回文边界里 ; 暴力扩
情况2:
当前点,在 最右回文边界内部, (c一定在i的左侧)
根据 i关于c的对称点i’ 的位置进行讨论:
2.1: [L ( i’ ) c i R]
i’的 回文区域 在[L,R]里, 则可得到 i的回文区域 =i’的回文区域
2.2:( [L i’ ) c i R]
i’的 回文区域 部分跑到L外面了 ,则 i的回文区域 为[ 2*i-R , R]
2.3: [L( i’ ) c i R]
i’的 回文区域 压线 L, 能确定一部分,还可以尝试着扩确定
#include<bits/stdc++.h>
using namespace std;
string x;
int getmaxlen(string str) {
int parr[str.length()];
int C = -1;
int R = -1;
int maxx = -1;
for(int i=0; i<str.length(); i++) {
parr[i] = R > i ? min(parr[2*C-i] , R-i):1;
while(i+parr[i] < str.length() && i-parr[i] > -1) {
if(str[i+parr[i]]==str[i-parr[i]]) {
parr[i]++;
} else {
break;
}
}
if(i+ parr[i] > R) {
R = i + parr[i];
C = i;
}
maxx = max(maxx,parr[i]);
}
return maxx-1;
}
int main() {
while(cin>>x) {
string t="#";
for(int i=0; i<x.size(); i++) {
t+=x[i];
t+='#';
}
cout<<getmaxlen(t)<<endl;
}
return 0;
}