-
总时间限制:
- 1000ms 内存限制:
- 1024kB
-
描述
-
有一种特殊的二进制密码锁,由n个相连的按钮组成(n<30),按钮有凹/凸两种状态,用手按按钮会改变其状态。
然而让人头疼的是,当你按一个按钮时,跟它相邻的两个按钮状态也会反转。当然,如果你按的是最左或者最右边的按钮,该按钮只会影响到跟它相邻的一个按钮。
当前密码锁状态已知,需要解决的问题是,你至少需要按多少次按钮,才能将密码锁转变为所期望的目标状态。
输入
- 两行,给出两个由0、1组成的等长字符串,表示当前/目标密码锁状态,其中0代表凹,1代表凸。 输出
- 至少需要进行的按按钮操作次数,如果无法实现转变,则输出impossible。 样例输入
-
011 000
样例输出
-
1
-
/* * 思路:1.从左往右 不相同的就按下一个 因为这样不会改变前面的结果 2. 不过对于第一个按钮 是可以按他自己的 因为按了他自己也不会改变前面的结果 所以最终结果就是1,2中的最小值 */
/* * 这是郭伟老师 用位运算写的- - 因为字符串长度小于30且只为0 1,故可以用int来模拟。 */ #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); else n &= ~(1 << i); } inline void FlipBit(int & n, int i) { n ^= (1 << i); } inline int GetBit(int n, int i) { return (n >> i) & 1; } int main() { char line[40]; destLock = lock = oriLock = 0; 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) { //p 代表最左边按钮 lock = oriLock; int times = 0; int curButton = p; for (int i = 0; i < N; ++i) { if (curButton) { ++times; if (i > 0) FlipBit(lock, i - 1); FlipBit(lock, i); if (i < N - 1) 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; }
-
/* 数组版的 最先参考的谁的忘了 这题开始我是不会的- -*/ #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; string aa,bb; int a[34],b[34],n,ans=0,ans2=0,c[34]; int main() { cin>>aa>>bb; for(int i=0;i<aa.length();i++) a[i+1]=aa[i]-'0',b[i+1]=bb[i]-'0',c[i+1]=aa[i]-'0'; n=aa.length(); for(int i=2;i<=n;i++) { if(a[i-1] != b[i-1]) { a[i-1] ^= 1;a[i] ^= 1;a[i+1] ^= 1; ++ans; } } int t=1,t1=1; for(int i=1;i<=n;i++) if(a[i]!=b[i]){t=0;break;}; c[1]^=1;c[2]^=1;++ans2; for(int i=2;i<=n;i++) { if(c[i-1] != b[i-1]) { c[i-1] ^= 1;c[i] ^= 1;c[i+1] ^= 1; ++ans2; } } for(int i=1;i<=n;i++) if(c[i]!=b[i]){t1=0;break;} if(t1&&t)return cout<<min(ans,ans2)<<endl ,0 ; if(t) return cout<< ans <<endl ,0; if(t1) return cout<< ans2 <<endl ,0; puts("impossible"); return 0;