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;
}
原文地址:https://www.cnblogs.com/yun-an/p/10914040.html