牛客小白月赛13 B题


链接:https://ac.nowcoder.com/acm/contest/549/B
来源:牛客网

小A非常喜欢回文串,当然我们都知道回文串这种情况是非常特殊的。
所以小A只想知道给定的一个字符串的最大回文子串是多少,但是小A对这个结果并不是非常满意。
现在小A可以对这个字符串做一些改动,他可以把这个字符串最前面的某一段连续的字符(不改变顺序)移动到原先字符串的末尾。
那么请问小A通过这样的操作之后(也可以选择不移动)能够得到最大回文子串的长度是多少。

题意:求n个串的最大回文子串的长度的最大值。
思路:枚举每一个变化后的字符串,对每个串跑一遍马拉车即可。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6;
char str[maxn];
char s1[maxn], s2[maxn];
int len1, len2;
int p[maxn];
 
void init() {
    len1 = strlen(s1);
    s2[0] = '@';
    s2[1] = '#';
    for (int i = 0; i < len1; i++) {
        s2[i * 2 + 2] = s1[i];
        s2[i * 2 + 3] = '#';
    }
    len2 = len1 * 2 + 2;
    s2[len2] = '$';
}
 
int manachar() {
    int mx = 0, id = 0;
    for (int i = 1; i < len2; i++) {
        if (mx > i) {
            p[i] = min(mx - i, p[2 * id - i]);
        } else {
            p[i] = 1;
        }
        while (s2[i + p[i]] == s2[i - p[i]]) {
            p[i]++;
        }
        if (i + p[i] > mx) {
            mx = i + p[i];
            id = i;
        }
    }
    int ans = 0;
    for (int i = 1; i < len2; i++) {
        ans = max(ans, p[i]);
    }
    return ans;
}
 
 
int main() {
    cin >> str;
    int n = strlen(str);
    int ans = 0;
    for (int i = 0; i < n; i++) {
        len1 = 0;
        for (int j = i; j < n; j++, len1++) {
            s1[len1] = str[j];
        }
        for (int j = 0; j < i; j++, len1++) {
            s1[len1] = str[j];
        }
        init();
        ans = max(ans, manachar());
    }
    cout << ans - 1<< endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37520038/article/details/89356502