問題描述
小明正在玩一個“翻硬幣”的遊戲。
桌上放着排成一排的若干硬幣。我們用 * 表示正面,用 o 表示反面(是小寫字母,不是零)。
比如,可能情形是:oo*oooo
如果同時翻轉左邊的兩個硬幣,則變爲:oooo***oooo
現在小明的問題是:如果已知了初始狀態和要達到的目標狀態,每次只能同時翻轉相鄰的兩個硬幣,那麼對特定的局面,最少要翻動多少次呢?
我們約定:把翻動相鄰的兩個硬幣叫做一步操作。輸入格式
兩行等長的字符串,分別表示初始狀態和要達到的目標狀態。每行的長度<1000輸出格式
一個整數,表示最小操作步數。樣例輸入1
oo
樣例輸出1
5
樣例輸入2
ooo***
ooo***
樣例輸出2
1
題解:
這道題說是貪心,但我總感覺對應到題解,這兩字很模糊(可能是我還理解的不夠好),題解: 比較兩個字符串,發現有不相同的字符(
s[i] != e[i]
),就將s的i和i+1翻轉,然後繼續從i=0比較,直到兩個字符串相等,記錄翻轉次數。
**但是其實我也不知道怎麼證明:這樣的翻轉次數就是最小的? **
代碼:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <deque>
#include <list>
#include <utility>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <bitset>
#include <iterator>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double E = exp(1.0);
const int MOD = 1e9+7;
const int MAX = 1e5+5;
string s,e;
int len;
int num;
void reverseStr(int i)
{
//cout << endl << "翻轉前:" + s << endl;
if(s[i] == 'o')
{
s[i] = '*';
}
else
{
s[i] = 'o';
}
if(s[i+1] == 'o')
{
s[i+1] = '*';
}
else
{
s[i+1] = 'o';
}
//cout << "翻轉後:" + s << endl;
}
int main()
{
/*
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
*/
cin >> s >> e;
int i = 0;
len = s.length();
while(i < len)
{
//cout << i << " ";
if(s[i] != e[i])
{
reverseStr(i);// 翻轉字符串s的i和i+1位置的字符
num++;
i = 0;// 重新從開始比較
}
else
{
i++;
}
}
cout << num << endl;
return 0;
}