AcWing 1208.翻硬币

链接:https://www.acwing.com/problem/content/description/1210/
题目:
小明正在玩一个“翻硬币”的游戏。

桌上放着排成一排的若干硬币。我们用 * 表示正面,用 o 表示反面(是小写字母,不是零)。

比如,可能情形是:**oo***oooo

如果同时翻转左边的两个硬币,则变为:oooo***oooo

现在小明的问题是:如果已知了初始状态和要达到的目标状态,每次只能同时翻转相邻的两个硬币,那么对特定的局面,最少要翻动多少次呢?

我们约定:把翻动相邻的两个硬币叫做一步操作。

输入格式
两行等长的字符串,分别表示初始状态和要达到的目标状态。

输出格式
一个整数,表示最小操作步数

数据范围
输入字符串的长度均不超过100。
数据保证答案一定有解。

输入样例1:


o****o****
输出样例1:
5
输入样例2:
*o**o***o***
*o***o**o***
输出样例2:
1
思路:
我记得以前做过这道题,但是现在做又忘了,我知道是贪心的思路,看了一眼题解就会写了。
从前到后遍历,只要有硬币不同,就翻转当前硬币和后一枚硬币,最后一定就能保证翻转次数就是最少的次数。
因为对于第一个不同的硬币来说,这样能保证它只会被翻转一次,也就是被翻转过去之后就不会被翻转回来,这样就能保证次数是最小的
题解:

#include <bits/stdc++.h>
using namespace std;

int ans;  //保存答案 

int main()
{
	string s1,s2;
	cin>>s1>>s2;
	int l=s1.size();
	for(int i=0;i<l;i++)  //从前往后遍历,只需要一次遍历
		if(s1[i]!=s2[i])  //对于每个不同的硬币,不用思考直接翻转
		{
			ans++;
			if(s1[i+1]=='*') s1[i+1]='o'; //因为不需要第二次遍历,所以其实不需要翻转下标为i的硬币
			else s1[i+1]='*';				//只需翻转下标为i+1的硬币
		}
	cout<<ans;
	return 0; 
}
posted @ 2021-11-19 15:45  longwind7  阅读(75)  评论(0编辑  收藏  举报