AcWing 1208.翻硬幣
阿新 • • 發佈:2021-11-19
連結: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; }