zoukankan      html  css  js  c++  java
  • (枚举)8469:特殊密码锁

    问题描述 
    有一种特殊的二进制密码锁,由n个相连的按钮组成(n<30),按钮有凹/凸两种状态,用手按按钮会改变其状态。然而让头疼的是,当你按一个按钮时,跟它相邻的两个按钮状态也会反转。当然,如果你按的是最左或者最右边的按钮,该按钮只会影响到跟它相邻的一个按钮。当前密码锁状态已知,需要解决的问题是,你至少需要按多少次按钮,才能将密码锁转变为所期望的目标状态。 


    输入 
    两行,给出两个由0、1组成的等长字符串,表示当前/目标密码锁状态,其中0代表凹,1代表凸。 


    输出 
    至少需要进行的按按钮操作次数,如果无法实现转变,则输出 impossible。 


    样例输入 
    011 
    000 


    样例输出 
    1

    我の思考

    此题想要用枚举法来解决,那我们就应该找出可能的几种情况。我们研究过这个机制后会发现,影响按钮改变的其实就是周围的按钮。但是在这里,我们会发现,第一个按钮的按与否,会影响到后面所有的按钮,也就是说,这里的枚举是枚举出当按下第一个按钮和不按第一个按钮的情况。而其他的,就只要找到一个不和目标对应为相等的按钮,我们按下它的下一个即可。

    我の代码

    #include <iostream>
    #include <stdlib.h>
    #include <string.h>
    using namespace std;
    int result=1<<30;
    int result2=0;
    int len=0;
    void flipNum(char* a,int i){
        if(a[i] == '1'){
            a[i] ='0';
        }
        else {
            a[i] = '1';
        }
    }
    
    //比较是否相同
    int cmpNum(char* a,char* b){
        int i=0;
    
        for(;i<len;i++){
            if(a[i]!=b[i]){
               return false;
            }
        }
        return true;
    }
    
    //设置反转
    void setArray(char* a,int i){
        flipNum(a,i);
        if(i == 0){
            flipNum(a,i+1);
        } else {
            flipNum(a,i-1);
            flipNum(a,i+1);
        }
        result2++;
    }
    
    //获取次数最小的
    int minNum(int i,int j){
        if(i<j)
            return i;
        else
            return j;
    }
    
    int main()
    {
        char origin[35];
        char aim[35];
    
        cin>>origin;
        cin>>aim;
    
        len  = strlen(origin);
        //处理数据
    
        if(cmpNum(origin,aim)){
            result = minNum(result,result2);
            return 0;
        }
        char c[35];
    
    
        for(int p=0;p<2;p++){
            result2=0;
            memcpy(c,origin,len);
            if(p==1){
                setArray(c,0);
                if(cmpNum(c,aim)){
                    result = minNum(result,result2);
                }
            }
    
            for(int i=0;i<len-1;i++){
                if(c[i] != aim[i]){
                        setArray(c,i+1);
                        if(cmpNum(c,aim)){
                            result = minNum(result,result2);
                        }
                }
            }
        }
    
        if(result == 1<<30)
            cout<<"impossible";
        else
            cout << result;
        return 0;
    }

    我の小结

    此外,因为我也算是一个算法学习上的新人,在很多细节处理的地方都不好。通过这个例子,我应该注意到,如果是最小的次数,一定要记得把所有的情况都经历过一次,再取最小的。还有数组设置长度的时候,最好设大一点点,可以提高容纳错误的能力,另外就是一些常用函数的对应头文件啊之类的要记忆一下QAQ。

  • 相关阅读:
    angularjs: ng-select和ng-options
    angularjs之$timeout指令
    angular的uiRouter服务学习(5) --- $state.includes()方法
    深究AngularJS——如何获取input的焦点(自定义指令)
    深究AngularJS——自定义服务详解(factory、service、provider)
    AngularJS 事件指令/input相关指令/样式指令/DOM操作指令详解
    字符串对象的创建
    redis安装和配置
    Cent Linux启动tomcat慢的问题
    Linux环境nginx的配置
  • 原文地址:https://www.cnblogs.com/rimochiko/p/7486925.html
Copyright © 2011-2022 走看看