Say No to Palindromes

传送门

题意:
一个字符串s, 只由a, b, c三种字符构成,有m次询问,每次询问一个区间l, r,可以操作使l, r子串的某个字符改变,问需要的最少的次数使得,l, r区间之内的字符串,没有回文


思路:
题目说字符串只由三个字符构成,这个条件很特殊,然后通过观察发现,要构成回文串只能是abcabc, acbacb, 等,连续的三个字符必须是要不相等的,而且这就构成了上述的规律,abc的全排列有6中,分别讨论这6要变成这6中情况需要的消耗,答案就是6中答案里面的最小值


总结:
字符串的特殊性利用,循环节来构成无回文串的字符串,要求区间,只要区间相减,最后求min即可

点击查看代码
#include <bits/stdc++.h>
#define endl '\n'
#define IOS ios::sync_with_stdio(false);
using namespace std;

typedef long long ll;
const int MAXN = 2e5 + 10;
int n, m;	
string s;
int dp[6][MAXN];

int main()
{
	IOS; cin.tie(0), cout.tie(0);
	cin >> n >> m;
	cin >> s;
	string temps = "abc";
	int pos = 0;
	do
	{
		for (int i = 0; i < s.size(); ++i)
		{
			if (i % 3 == 0)
			{
				if (s[i] != temps[0])
					dp[pos][i] = (i == 0) ? 1 : dp[pos][i - 1] + 1;
				else
					dp[pos][i] = (i == 0) ? 0 : dp[pos][i - 1];
			}
			else if (i % 3 == 1)
			{
				if (s[i] != temps[1])
					dp[pos][i] = (i == 0) ? 1 : dp[pos][i - 1] + 1;
				else
					dp[pos][i] = (i == 0) ? 0 : dp[pos][i - 1];
			}
			else if (i % 3 == 2)
			{
				if (s[i] != temps[2])
					dp[pos][i] = (i == 0) ? 1 : dp[pos][i - 1] + 1;
				else
					dp[pos][i] = (i == 0) ? 0 : dp[pos][i - 1];
			}
		}
		++pos;
	} while (next_permutation(temps.begin(), temps.end()));
	

	while (m--)
	{
		int l, r;
		cin >> l >> r;
		l -= 1, r -= 1;
		int ans = min({ dp[0][r] - dp[0][l - 1], dp[1][r] - dp[1][l - 1], dp[2][r] - dp[2][l - 1], dp[3][r] - dp[3][l - 1], dp[4][r] - dp[4][l - 1], dp[5][r] - dp[5][l - 1] });
		cout << ans << endl;
	}
	
	return 0;
}
/*
1 1
baacb
2 3
*/
posted @ 2022-10-07 19:30  YUGUOTIANQING  阅读(20)  评论(0)    收藏  举报