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;
}
posted @ 2025-03-31 13:08  Natural_TLP  阅读(22)  评论(0)    收藏  举报