8469:特殊密码锁
- 总时间限制:
- 1000ms
- 内存限制:
- 1024kB
- 描述
-
有一种特殊的二进制密码锁,由n个相连的按钮组成(n<30),按钮有凹/凸两种状态,用手按按钮会改变其状态。
然而让人头疼的是,当你按一个按钮时,跟它相邻的两个按钮状态也会反转。当然,如果你按的是最左或者最右边的按钮,该按钮只会影响到跟它相邻的一个按钮。
当前密码锁状态已知,需要解决的问题是,你至少需要按多少次按钮,才能将密码锁转变为所期望的目标状态。
- 输入
- 两行,给出两个由0、1组成的等长字符串,表示当前/目标密码锁状态,其中0代表凹,1代表凸。
- 输出
- 至少需要进行的按按钮操作次数,如果无法实现转变,则输出impossible。
- 样例输入
-
011 000
- 样例输出
-
1
一道好坑的贪心啊。
//在想万复赛T1考这个是不是直接滚粗。。
对于一个按钮 如果和规定的不一样 要么按第一个 要么按第二个
如果从左往右考虑 对于每一个不同的按钮 都按下一个 这样不影响以后的情况
从第一个按钮开始做一次 并记录结果
从第二个按钮开始做一次 并记录结果
如果第一次第二次的结果都满足 则输出二者操作的最小值
如果仅满足一次就输出那一次的操作数
如果都不满足就是输出impossible
【只做一次从第一个按钮开始的反例:100 001】#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; }
//另外虽然紫书把在循环中i<aa.length()视为错误但是实际上会慢一点 也是能用的 不放心的话就 改一改咯