翻硬币-蓝桥杯
小明正在玩一个“翻硬币”的游戏。
桌上放着排成一排的若干硬币。我们用 * 表示正面,用 o 表示反面(是小写字母,不是零)。
比如,可能情形是:**oooooo
如果同时翻转左边的两个硬币,则变为:oooooooo
现在小明的问题是:如果已知了初始状态和要达到的目标状态,每次只能同时翻转相邻的两个硬币,那么对特定的局面,最少要翻动多少次呢?
我们约定:把翻动相邻的两个硬币叫做一步操作。
输入格式
两行等长的字符串,分别表示初始状态和要达到的目标状态。
输出格式
一个整数,表示最小操作步数
数据范围
输入字符串的长度均不超过100。
数据保证答案一定有解。
输入样例1:
********** o****o****
输出样例1:
5
输入样例2:
*o**o***o*** *o***o**o***
输出样例2:
1
最主要的当然是分析出一种方法能让他和目标答案一致,因为每次要翻两枚一样的硬币,也就是说会对周围的硬币有影响,也是类似于费解的开关的问题,不过要稍微简单一些,我们每次都跟目标的字符串进行对照,如果当前位置不匹配的话,我们就翻转当前位置和后面的一个位置的硬币,这样就能保证前面所有的硬币都是和目标所匹配的,因为题目说给的答案一定是有解的,所以翻转到倒数第二个之后那么就一定是答案了
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N = 110; char source[N], target[N]; //翻转第i个位置的硬币 void turn(int i) { if(source[i] == '*') source[i] = 'o'; else source[i] = '*'; } int main() { cin >> source >> target; int n = strlen(source); int res = 0; //每次有不一样的就翻转当前的和他后面的一个硬币,最后一个硬币不可以被翻转 for(int i = 0 ; i < n - 1 ; i ++ ) { if(source[i] != target[i]) { turn(i), turn(i + 1); res ++; } } cout << res << endl; return 0; }
这里用到了strlen函数,它返回的长度是不包含最后的那个结束符的,比如说字符串 'abcdefg' 返回值就是7