特殊密码锁

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;
}
View Code

//另外虽然紫书把在循环中i<aa.length()视为错误但是实际上会慢一点 也是能用的 不放心的话就 改一改咯












posted @ 2016-09-11 15:26  pandaB  阅读(942)  评论(0编辑  收藏  举报