有趣的二进制
题目描述
最近北京大学药学院的小晨在计概课上学习到二进制之后对其产生了浓厚的兴趣,在每次操作仅能移动相邻的0和1的前提下,她想知道把一个二进制数转换成另一个二进制数的最小操作数。
关于输入
输入共三行:
第一行为一个整数n (0 < n <= 200),代表二进制数的位数
第二行为第一个二进制数的每一位
第三行为第二个二进制数的每一位
关于输出
输出将第一个二进制数转换为第二个二进制数的最少操作数,如果答案不存在,则输出-1
例子输入
7 1 1 0 1 0 0 1 0 1 1 0 0 1 1
例子输出
4
解题分析
要解决本题,即寻求最小操作数,则要先想想怎么才能够操作最少次数,不失一般性,我们从第一个输入的二进制数的第一位开始遍历,如果发现它与目标二进制数不一样,则我们直接从该位的下一位开始找起,找到与目标二进制数该位相同的数后,再从后往前依次交换到当前位置,然后继续重复该操作即可。为什么这样就最少了呢?其实不难想象,比如0 1 1 0 0 0 1和1 1 1 0 0 0 0,我们把最后一位1直接依次交换直到第一位,和我先把最近的1捞过来用,然后重复操作,次数是一致的。
代码实现
#include <bits/stdc++.h>
using namespace std;
int main(){
int n; cin>>n;
int a[n],b[n]; int countA=0,countB=0;
for(int i=0;i<n;i++){
cin>>a[i];
if(a[i]) countA++;
}
for(int i=0;i<n;i++){
cin>>b[i];
if(b[i]) countB++;
}
if(countA!=countB){
cout<<-1<<endl; return 0;
}
else{
int count=0;
for(int i=0;i<n;i++){
if(a[i]!=b[i]){
for(int j=i+1;j<n;j++){
if(a[j]==b[i]){
for(int k=j;k>=i+1;k--){
swap(a[k],a[k-1]);
count++;
}
break;
}
}
}
}
cout<<count<<endl;
}
return 0;
}