有一种特殊的二进制密码锁,由n个相连的按钮组成(n<30),按钮有凹/凸两种状态,用手按按钮会改变其状态。
然而让人头疼的是,当你按一个按钮时,跟它相邻的两个按钮状态也会反转。当然,如果你按的是最左或者最右边的按钮,该按钮只会影响到跟它相邻的一个按钮。
当前密码锁状态已知,需要解决的问题是,你至少需要按多少次按钮,才能将密码锁转变为所期望的目标状态。
两行,给出两个由0、1组成的等长字符串,表示当前/目标密码锁状态,其中0代表凹,1代表凸。
至少需要进行的按按钮操作次数,如果无法实现转变,则输出impossible。
011
000
1
使用两个int型的变量保存初始值和最终值,通过位运算改变每个bit的状态。枚举第一个bit也就是第一个按钮的两种情况,按下第一个按钮,第一个bit反转后可能的按键次数,这是第一种情况;不按下第一个按钮,第一个bit不发生反转后续可能的案件次数,这是第二种情况。
# include <iostream> # include <cstring> # include <string> # include <memory> using namespace std; int Getbit(int a, int i) { return (a>>i)&1; } int Setbit(int &a, int i, int b) { if(b) a |= (1<<i); else a &= ~(1<<i); } int Filtbit(int &a, int i) { a ^= (1<<i); } int OutputResult(int result) { if(result>=0) cout<<result; else cout<<"impossible"; } int main() { int init=0,mid=0,end=0,cnt=0,result1=0,result2=0; char line[30]; //输入数据 cin>>line; cnt = strlen(line); for(int i=0;i<cnt;i++) Setbit(init,i,line[i]-'0'); cin>>line; for(int i=0;i<cnt;i++) Setbit(end,i,line[i]-'0'); //不按下第一个按钮的情况 mid = init; for(int i=0;i<cnt-1;i++){ if(Getbit(mid,i)!=Getbit(end,i)){ Filtbit(mid,i); Filtbit(mid,i+1); if(i<cnt-2&&i!=0) Filtbit(mid,i+2); result1++; } if(mid==end){ OutputResult(result1); break; } } //按下第一个按钮的情况 if(mid!=end) { mid = init; //按下第一个按钮 Filtbit(mid,0); Filtbit(mid,1); result2++; for(int i=0;i<cnt-1;i++){ if(Getbit(mid,i)!=Getbit(end,i)){ Filtbit(mid,i); Filtbit(mid,i+1); if(i<cnt-2) Filtbit(mid,i+2); result2++; } if(mid==end){ OutputResult(result2); break; } } } if(cnt==1){ result1 = 1; OutputResult(result1); } else if(mid!=end){ result1 = -1; OutputResult(result1); } return 0; }