关键是要想清楚,最边上可以翻转,也可以不翻转,在这两种情况定下来后,后面的逐一比较。实际上这就是最少的操作数
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int oriLock;
int lock;
int destLock;
inline void SetBit(int & n,int i,int v)
{
if(v)
n |= (1 << i); //把第i位设为1
else
n &= ~(1 << i); //把第i位设为0
}
inline void FlipBit(int & n,int i)
{
n ^= (1 << i); //反转第i位
}
inline int GetBit(int n,int i)
{
return (n >> i) & 1; //取出第i位
}
int main()
{
char line[40]; //字符数组储存二进制数字
destLock = lock = oriLock = 0; //oriLock为原始结果,destLock为目标结果
cin >> line;
int N = strlen(line); //长度
for(int i = 0; i < N; ++i) //将字符串转化为二进制数字
SetBit(oriLock,i, line[i] - '0');
cin >> line;
for(int i = 0; line[i]; ++i)
SetBit(destLock,i, line[i] - '0');
int minTimes = 1 << 30;
for(int p = 0; p < 2; ++p) {
lock = oriLock;
int times = 0;
int curButton = p;
for(int i = 0; i < N; ++i) {
if(curButton) {
++ times;
if( i > 0) //如果i大于0,那么i后一位也翻转
FlipBit(lock,i-1);
FlipBit(lock,i);
if( i < N-1) //如果i小于N-1,那么i前一位也翻转
FlipBit(lock,i+1);
}
if( GetBit(lock,i) != GetBit(destLock,i)) //
curButton = 1; //执行翻转
else
curButton = 0; //否就跳过
}
if( lock == destLock)
minTimes = min(minTimes ,times);
}
if( minTimes == 1 << 30)
cout << "impossible" << endl;
else
cout << minTimes << endl;
return 0;
}