2023年蓝桥杯省赛C++c组真题 翻转 知识点:贪心

137 阅读2分钟

题目:5.翻转 - 蓝桥云课 (lanqiao.cn)

视频解析:[蓝桥杯]真题讲解:翻转(贪心)_哔哩哔哩_bilibili

思想

题目要求我们求最小操作次数

比如说s串与t串有3处不同,那么我要修改3次才能把s串变为t串。那么最小操作步数是说我可能修改了1个地方,另外两个地方会被我这个位置的修改所影响也变为了期望值,那么1次操作就把s串变为t串了,此时最小操作步数就是1。

我们需要判断本题是否存在修改一个地方会影响其他原本要修改的地方的值的情况。

我们用贪心去做,也就是我们要去找一个规律,使得我们找到的规律可以减少我们考虑的方案数量。

我们发现了两个规律:

第一个规律是首尾无法修改。因此不用考虑修改首尾的方案

101和010都是a[i-1]=a[i+1]&&a[i]!=a[i-1]的格式,

首没有i-1,尾没有i+1,因此无法修改。所以我们对修改首位的情况就不用考虑了。

如果t串与s串首尾不相同,因为首尾不能修改,所以s串无论如何也变不为t串,直接输出-1即可。如果s串和t串首尾相同,那就不用修改。

第二个规律,邻居不能被修改

我们发现只要修改两个绿框的值就可以把s串变为t串: image.png

我们先修改第一个要修改的位置的值:

image.png

此时我们发现修改完之后第一个修改值后面的邻居就不满足修改条件了,无法进行修改。那么我们第二个想要修改的值就不会被前面的值所影响。

因此每一次修改都不会影响其他的修改,对于一个s串来说,有多少个地方与t串不同,就需要修改多少次,修改次数就是最小操作次数。

我们的策略就是从前往后依次能修改的进行修改。

code

#include<bits/stdc++.h>
using namespace std;
int cnt;
int main()
{
	int t; cin >> t;
	while (t--)
	{
		int cnt = 0;
		string t, s; cin >> t >> s;

		for (int i = 1; i < s.size()-1; i++)
		{
			if (s[i] == t[i])continue;

			if (s[i - 1] == s[i + 1] && s[i] != s[i - 1])
			{
				s[i] = t[i];
				cnt++;
			}

		}
    	if (s == t)
			{
				cout << cnt << endl;
			}
			else
			{
				cout << -1 << endl;
			}
	}
	return 0;
}