• 【贪心算法】特殊的密码锁(openjudge8469)


    a:特殊密码锁

    总时间限制:
    1000ms
    内存限制:
    1024kB
    描述

    有一种特殊的二进制密码锁,由n个相连的按钮组成(n<30),按钮有凹/凸两种状态,用手按按钮会改变其状态。

    然而让人头疼的是,当你按一个按钮时,跟它相邻的两个按钮状态也会反转。当然,如果你按的是最左或者最右边的按钮,该按钮只会影响到跟它相邻的一个按钮。

    当前密码锁状态已知,需要解决的问题是,你至少需要按多少次按钮,才能将密码锁转变为所期望的目标状态。

    输入
    两行,给出两个由0、1组成的等长字符串,表示当前/目标密码锁状态,其中0代表凹,1代表凸。
    输出
    至少需要进行的按按钮操作次数,如果无法实现转变,则输出impossible。
    样例输入
    011
    000
    样例输出
        1

    思路:看到输入输出首先想到的是枚举所有按钮的状态,但是n的范围为30,所以会有2的30次方多种,所以肯定不能枚举出所有状态,于是想了一个贪心策略,从左往右,如果按钮不匹配就按下一个按钮,始终让左面的按钮是匹配的,如果遍历到最后一个按钮不匹配则"impossible",否则输出最少的按钮次数。但是我忽略了一个特殊情况即前两个按钮,当前两个按钮不匹配时既可以按第一个按钮也可以按第二个按钮,所以应当考虑这两种情况最后哪中情况按的次数少。由于我写的代码比较复杂,所以找了个大佬的代码如下:

    #include <iostream>
    #include <string>
    #include <algorithm>
    using namespace std;
    string s,t,fin;
    int tmp=0,ans=1e9,n;
    /*字符串中'1'与'0'的转换值得学习*/
    inline void flip(int i){
        s[i-1]=s[i-1]=='1'?'0':'1';
        s[i]=s[i]=='1'?'0':'1';
        if(i+1<n) s[i+1]=s[i+1]=='1'?'0':'1';
    }
    int main(int argc, const char * argv[]) {
        cin>>s>>fin;t=s;
        n=s.size();
        //第一种情况:按钮不匹配按后面的按钮
        for(int i=1;i<n;i++)
            if(s[i-1]!=fin[i-1]){
                flip(i); tmp++;
            }
        if(s[n-1]==fin[n-1]) ans=tmp;
        //第二种情况:如果前两个按钮不匹配,按第一个按钮,其他按钮不匹配还是按后一个按钮
        tmp=1;
        s=t;
        //原作者没有加这个判断,加上判断代码更清晰一些。
        if(s[0]!=fin[0]||s[1]!=fin[1]){
            s[0]=s[0]=='1'?'0':'1';
        s[1]=s[1]=='1'?'0':'1';
        for(int i=1;i<n;i++)
            if(s[i-1]!=fin[i-1]){
                flip(i); tmp++;
            }
        }
    
        //按完以后如果最后一个按钮相同,则输出两种情况中的按的次数最少的情况。
        if(s[n-1]==fin[n-1]) ans=min(ans,tmp);
        //如果不同,则
        if(ans==1e9) cout<<"impossible";
        else cout<<ans;
        return 0;
    }

    代码改自:http://www.cnblogs.com/candy99/p/5791488.html

    祝你早日攒够失望,然后开始新的生活。
  • 相关阅读:
    如何学习掌握一门新技术
    Linux多线程编程(不限Linux)
    腾讯后台开发面试题2
    腾讯后台开发面试题
    【转】Linux杀死fork产生的子进程的僵尸进程defunct
    【转】Linux网络编程入门
    【转】揭开Socket编程的面纱
    【转】简单理解socket
    【转】404、500、502等HTTP状态码介绍
    【转】fread函数和fwrite函数
  • 原文地址:https://www.cnblogs.com/LuRenJiang/p/7149184.html
Copyright © 2020-2023  润新知