[蓝桥杯 2013 省 B] 翻硬币
题目背景
小明正在玩一个“翻硬币”的游戏。
题目描述
桌上放着排成一排的若干硬币。我们用 *
表示正面,用 o
表示反面(是小写字母,不是零),比如可能情形是 **oo***oooo
,如果同时翻转左边的两个硬币,则变为 oooo***oooo
。现在小明的问题是:如果已知了初始状态和要达到的目标状态,每次只能同时翻转相邻的两个硬币,那么对特定的局面,最少要翻动多少次呢?
输入格式
两行等长字符串,分别表示初始状态和要达到的目标状态,每行长度小于 1000 1000 1000。
数据保证一定存在至少一种方案可以从初始状态和要达到的目标状态。
输出格式
一个整数,表示最小操作步数。
样例 #1
样例输入 #1
**********
o****o****
样例输出 #1
5
样例 #2
样例输入 #2
*o**o***o***
*o***o**o***
样例输出 #2
1
提示
source:蓝桥杯 2013 省 B 组 H 题
所需变量
int arr[2][1005];//用于存储初始状态和终止状态硬币的状况
int sum = 0;//用于记录翻转次数
int i;//循环变量
int control = 0;//用于记录这个字符串的长度
思路:我们首先仔细分析不难发现,就是遍历,如果遇到两个不一样的我们就开始翻转,顺带着后面一个也跟着翻转,直至到结束都翻转过来!
首先是将字符串读入,我的做法是一个一个字符的读取,读入代码如下:
for(i = 0;i<2;i++){
control = 0;
while(~scanf("%c",&temp)){
if(temp == '\n'){
break;
}
if(temp == '*'){
arr[i][control] = 1;
}else{
arr[i][control] = 0;
}
control++;
}
}
将字符读入之后就开始进行比较,如果发现不一样,就是必须得翻转,然后下一个也是跟着翻转!部分代码如下:
for(i = 0;i<control;i++){
if(arr[0][i] != arr[1][i]){
sum++;
arr[0][i] = (arr[0][i]+1)%2;
arr[0][i+1] = (arr[0][i+1]+1)%2;
}
}
最后将初始状态翻转得到最终状态我们就算完成,因此完整代码如下(编译器是dev,语言是C语言):
#include<iostream>
using namespace std;
int main(){
int arr[2][1005],sum = 0,i,control = 0;
char temp;
for(i = 0;i<2;i++){
control = 0;
while(~scanf("%c",&temp)){
if(temp == '\n'){
break;
}
if(temp == '*'){
arr[i][control] = 1;
}else{
arr[i][control] = 0;
}
control++;
}
}
for(i = 0;i<control;i++){
if(arr[0][i] != arr[1][i]){
sum++;
arr[0][i] = (arr[0][i]+1)%2;
arr[0][i+1] = (arr[0][i+1]+1)%2;
}
}
cout<<sum<<endl;
return 0;
}