问题描述
小明正在玩一个“翻硬币”的游戏。
桌上放着排成一排的若干硬币。我们用 * 表示正面,用 o 表示反面(是小写字母,不是零)。
比如,可能情形是:oo*oooo
如果同时翻转左边的两个硬币,则变为:oooo***oooo
现在小明的问题是:如果已知了初始状态和要达到的目标状态,每次只能同时翻转相邻的两个硬币,那么对特定的局面,最少要翻动多少次呢?
我们约定:把翻动相邻的两个硬币叫做一步操作,那么要求:
输入格式
两行等长的字符串,分别表示初始状态和要达到的目标状态。每行的长度<1000
输出格式
一个整数,表示最小操作步数。
样例输入1
**********
o****o****
样例输出1
5
样例输入2
*o**o***o***
*o***o**o***
样例输出2
1
解题思路:
这个题可以暴力求解,但是细微观察一下,题目是有规律可循的:
(下面说说的翻转都是指依次翻转两个相邻的位置,同题目中的意思)
就用例子来说吧:
0 1 2 3 4 5 6 7 8 9
* * * o * * * o * *
* o * * * o * * * *
(用表格更容易看对其效果)
对于这两个链:只需要翻转4次就可以使两个链相同(只看出的),
那么规律就是每两个相邻的不同位置的下标之差的和就是所求的
最小次数(注意我说的是每两个相邻的位置,也就是每一个不同
的位置只能用一次)。对于上述两个链计算过程就是
3-1 = 2,7 - 5 = 2;那么结果就是2 + 2 = 4;
在比如:
0 1 2 3 4 5
* * * * * *
o * * * * o
这两个链需要翻转的最少次数为:5 - 0 = 5;即5次;
上面两个例子,大家应该都可以看出了吧;
或许有人想到了这个例子:
0 1 2 3 4 5 6 7 8 9
* * * * * * o * * *
* o * * * * * * * o
对于这两个链上面的规律就“失效了”,但是大家仔细观察,这种情况应该是无解的,
所以上面总结的规律是正确的。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int sum=0;
string a,b;
getline(cin,a);
getline(cin,b);
int len=a.length();
int start=-1,end=-1;
for(int i=0;i<len;i++){
if(a[i]!=b[i]){
if(start==-1)
start=i;
else{
sum+=i-start;
start=-1;
}
}
}
cout<<sum<<endl;
return 0;
}