HDU 3294 解题报告 Manacher 算法

来源:互联网 发布:eva到底讲了什么 知乎 编辑:程序博客网 时间:2024/05/22 17:16

题目意思:

对输入的字符串做两步处理,第一步先按要求转换。第二步在转换后的字符串中找出最长的回文子串。


最长回文子串可以用 Manacher 算法解决。参考这篇求最长回文子串之Manacher算法


代码:

#include <cstdio>#include <algorithm>#include <cstring>using namespace std;#define maxn 200005#define maxm maxn * 2char input[maxn];char str[maxm] = {'$', '#'};int  p[maxm];int longest_plalindrome(char *s, int *mxlen, int *index){//p[i] = min{p[2 * id - 1], mx - i}int len = strlen(s);int id = 0, mx = 0;*mxlen = 0;for (int i = 1; s[i] != '\0'; ++i) {p[i] = mx > i ? min(p[2 * id - i], mx - i) : 1;while (s[i + p[i]] == s[i - p[i]]) p[i]++;if ((i + p[i]) > mx) {mx = i + p[i];id = i;}if (*mxlen < p[i]) {*mxlen = p[i];*index = i;}}*mxlen -= 1;return *mxlen;}int main(){//freopen("testdata/3294.txt", "r", stdin);char c;int  d, len, pos, mxlen, index;while (scanf("%c %s", &c, input) != EOF) {d = c - 'a';len = strlen(input);pos = 2;for (int i = 0; input[i] != '\0'; ++i) {//step 1if (input[i] < c)input[i] = 'z' - (c - input[i] - 1);elseinput[i] -= d;str[pos++] = input[i];str[pos++] = '#';}str[pos] = '\0';longest_plalindrome(str, &mxlen, &index); //step 2if (mxlen < 2) printf("No solution!\n");else {int beg = (index - (mxlen - 2)) / 2 - 1;printf("%d %d\n", beg, beg + mxlen - 1);for (int i = beg; i < beg + mxlen; ++i)printf("%c", input[i]);printf("\n");}getchar();}return 0;}


0 0
原创粉丝点击