链接: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;
}