1. 程式人生 > 其它 >AcWing 1208.翻硬幣

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; 
}