问题描述
小明正在玩一个“翻硬币”的游戏。
桌上放着排成一排的若干硬币。我们用 * 表示正面,用 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;
}