(枚举)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。

原文地址:https://www.cnblogs.com/rimochiko/p/7486925.html