CCCC团体程序设计天梯赛 L2-008 最长对称子串
记录天梯赛题目合集 跳转查看
题目描述
对给定的字符串,本题要求你输出最长对称子串的长度。例如,给定Is PAT&TAP symmetric?,最长对称子串为s PAT&TAP s,于是你应该输出\(11\)。
输入格式:
输入在一行中给出长度不超过\(1000\)的非空字符串。
输出格式:
在一行中输出最长对称子串的长度。
输入样例:
Is PAT&TAP symmetric?
输出样例:
11
题目分析
这题题面很简单也很板,找给定字符串的最长对称子串的长度。这个最长对称子串也就是最长回文子串,我们回想求回文子串的几种方法:暴力、中心扩散、区间dp、哈希+二分、manacher(我个人所知就这5种),从时间复杂度着手,除了暴力的不可行,其他4种都可以通过这题,任选一种自己熟悉的写就行了。
我用的是manacher算法,这个算法可以在 \(O(n)\) 时间复杂度下求出最长的回文子串。
代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const ll inf = 1e18;
const int INF = 0x3f3f3f3f;
const int N = 1e6 + 10;
string s;
char str[N];
int p[N], len;
int manacher(string s)
{
str[len] = '!';
str[++ len] = '#';
for (int i = 0; i < s.size(); i ++) str[++ len] = s[i], str[++ len] = '#';
str[len + 1] = '@';
int rt = 0, mid = 0, res = 0;
for (int i = 1; i <= len; i ++) {
if (i >= rt) p[i] = 1;
else p[i] = min(p[2 * mid - i], rt - i);
while (str[i + p[i]] == str[i - p[i]]) p[i] ++;
if (i + p[i] > rt) {
rt = i + p[i];
mid = i;
}
res = max(res, p[i] - 1);
}
return res;
}
void solve()
{
getline(cin, s);
cout << manacher(s);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T = 1;
// cin >> T;
while (T --) solve();
return 0;
}

浙公网安备 33010602011771号