• POJ8469 特殊密码锁


    总时间限制: 1000ms 内存限制: 1024kB
    描述
    有一种特殊的二进制密码锁,由n个相连的按钮组成(n<30),按钮有凹/凸两种状态,用手按按钮会改变其状态。
    然而让人头疼的是,当你按一个按钮时,跟它相邻的两个按钮状态也会反转。当然,如果你按的是最左或者最右边的按钮,该按钮只会影响到跟它相邻的一个按钮。
    当前密码锁状态已知,需要解决的问题是,你至少需要按多少次按钮,才能将密码锁转变为所期望的目标状态。
    输入
    两行,给出两个由0、1组成的等长字符串,表示当前/目标密码锁状态,其中0代表凹,1代表凸。
    输出
    至少需要进行的按按钮操作次数,如果无法实现转变,则输出impossible。
    样例输入
    011
    000

    样例输出

    1 

    解题思路:

    由于第一个按钮是否按下会影响后面所有的按钮,因此枚举第一个按钮对应的两种情况。另外,如果按钮按下后和目标状态不相同,之前的情况已经枚举完毕,只需要按下下一个按钮即可。

    代码:

    #include <iostream>
    #include <cstring>
    using namespace std;
    
    int len = 0;
    int result = 1 << 30;//最终的结果
    int cnt = 0;//每次枚举得出的操作次数
    
    //将第i位反转
    void ReNum(char* a, int i) {
        if (a[i] == '1')
        {
            a[i] = '0';
        }
        else
        {
            a[i] = '1';
        }
    }
    
    //比较是否相同
    int cmp(char* a, char* b) {
        int i = 0;
    
        for (; i < len; i++) {
            if (a[i] != b[i]) {
                return false;
            }
        }
        return true;
    }
    
    //设置反转
    void Reversal(char* a, int i) {
        ReNum(a, i);
        if (i == 0) {
            ReNum(a, i + 1);
        }
        else {
            ReNum(a, i - 1);
            ReNum(a, i + 1);
        }
        cnt++;
    }
    
    //获取更小的
    int min(int i, int j) {
        if (i < j)
            return i;
        else
            return j;
    }
    
    int main()
    {
        char a[30];
        char target[30]; //初始状态和目标状态
        char temp[30];
    
        cin >> a >> target;
        len = strlen(a);
    
        if (cmp(a, target))//已经和目标状态相等
        {
            cout << 0;
            return 0;
        }
    
        for (int k = 0; k < 2; k++) //第一位反转与否
        {
            cnt = 0;//记录置零
            memcpy(temp, a, len);
    
            if (k == 1)//改变第一位
            {
                Reversal(temp, 0);
                if (cmp(temp, target))//如果这样就可以了,这个肯定是最小值
                {
                    result = min(result, cnt);//保存结果
                }
            }
            for (int i = 0; i < len - 1; i++)
            {
                if (temp[i] != target[i])
                {
                    Reversal(temp, i + 1);//如果不相等就改变下一位
                    if (cmp(temp, target))
                    {
                        result = min(result, cnt);//保存结果
                    }
                }
            }
        }
        if (result == 1 << 30) //如果没有成功过
            cout << "impossible";
        else
            cout << result;
        return 0;
    }
  • 相关阅读:
    SHELL脚本自动备份Linux系统
    Linux Shell脚本之自动修改IP
    oracle redo日志维护
    Linux运维工程师面试
    angular 的杂碎报错小知识
    angular.run 妙用
    vue的生命周期
    angular +H5 上传图片 与预览图片
    跨域问题解决方案之chrome插件
    js递归
  • 原文地址:https://www.cnblogs.com/yun-an/p/10914040.html
Copyright © 2020-2023  润新知