题目链接:点击打开链接
给你一个字符串, 让你输出这个字符串最长回文的起点和终点以及此回文串.
Manacher算法的应用, 记录最长回文时i的指, 通过i以及p[i]求出起点和终点, 比较棘手的是输出, 搞了大半天发现一句话就可以解决..
AC代码:
#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
using namespace std;
const int MAXN = 2e5 + 10;
char real_a, s[MAXN * 2];
int p[MAXN * 2];
int main(int argc, char const *argv[])
{
while(scanf("%c %s", &real_a, s) != EOF) {
getchar();
int len = strlen(s), id = 0, maxid = 0;
for(int i = len; i >= 0; --i) {
s[i * 2 + 2] = s[i];
s[i * 2 + 1] = '#';
}
s[0] = '$';
for(int i = 2; i < 2 * len + 1; ++i) {
if(p[id] + id > i) p[i] = min(p[id * 2 - i], p[id] + 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;
if(p[maxid] < p[i]) maxid = i;
}
if(p[maxid] - 1 < 2) printf("No solution!\n");
else {
printf("%d %d\n", (maxid - p[maxid] + 2) / 2 - 1, (maxid + p[maxid] - 2) / 2 - 1);
for(int i = maxid - p[maxid] + 2; i <= maxid + p[maxid] - 2; i += 2)
printf("%c", (s[i] - real_a + 26) % 26 + 'a');
printf("\n");
}
}
return 0;
}