一道Manachar求最长回文串的应用题
枚举每种翻转后的字符串并用Manachar求出其最长回文串
#include <iostream>
#include<algorithm>
#include<string>
using namespace std;
int p[10100];
string init(string s) {
string newStr;
newStr.append("$#");
for (int i = 0; i < s.length(); i++) {
newStr.append(1, s.at(i));// 添加一个字符
newStr.append("#");
}
return newStr;
}
int solve(string s) {
int id = 0;
int mx = 0;
int longest = -1;
for (int i = 1; i < s.length(); i++) {
if (i < mx) {
int j = 2 * id - i;
p[i] = min(p[j], mx - i);
}
else p[i] = 1;
while (s[i - p[i]] == s[i + p[i]]) {
p[i]++;
}
// updata
if (p[i] + i > mx) {
id = i;
mx = p[i] + i;
}
if (p[i] > longest) {
longest = p[i];
}
}
return longest - 1;
}
// 返回翻转后的字符串
string f(int end, string s) {
string newStr;
for (int i = end + 1; i < s.length(); i++) {
newStr.append(1, s[i]);
}
for (int i = 0; i <= end; i++) {
newStr.append(1, s[i]);
}
return newStr;
}
int main()
{
int ans = -1;
string str1;
cin >> str1;
string str2 = init(str1);
ans = solve(str2);
for (int i = 0; i < str1.length() - 1; i++) {
string newStr = f(i, str1);
str2 = init(newStr);
int temp = solve(str2);
if (temp > ans)ans = temp;
}
cout << ans;
return 0;
}