团体程序设计天梯赛-练习集
L2-008. 最长对称子串
https://www.patest.cn/contests/gplt/L2-008
用Manncher算法的模板题
#include<iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <string>
using namespace std;
string preProcess(const string &s);
int min(int a, int b) {
return a > b ? b : a;
}
string longestPalindrome(string s) {
const int len = s.size();
if (len <= 1)return s;
//Manncher算法 ,o(n)
string str = preProcess(s);
int n = str.size(), id = 0, mx = 0;
vector<int>p(n, 0);
for (int i = 1; i < n - 1; i++)
{
p[i] = mx > i ? min(p[2 * id - i], mx - i) : 1;
//if(mx <= i || (mx > i && p[2*id-i] == mx - i)) //根据正文斜体部分的注释,这里可要可不要
while (str[i + p[i]] == str[i - p[i]])p[i]++;
if (i + p[i] > mx)
{
mx = i + p[i];
id = i;
}
}
//遍历p,寻找最大回文长度
int maxLen = 0, index = 0;
for (int i = 1; i < n - 1; i++)
if (p[i] > maxLen)
{
maxLen = p[i];
index = i;
}
return s.substr((index - maxLen) / 2, maxLen - 1);
}
//预处理字符串,abc预处理后变成$#a#b#c#^
string preProcess(const string &s)
{
int n = s.size();
string res;
res.push_back('$');//把$放到字符串头部
res.push_back('#');//以#作为原来字符串中每个字符的间隔
for (int i = 0; i < n; i++)
{
res.push_back(s[i]);
res.push_back('#');
}
res.push_back('^');//以^作为字符串的结尾
return res;
}
int main() {
string A;
getline(cin,A);
cout << longestPalindrome(A).length() << endl;
return 0;
}