8469.特殊密码锁

8469.特殊密码锁

每个按钮有凹和凸两种状态,则n个按钮的状态总数为$ 2^{n} $,显然使用暴力解法会超出时间限制。显而易见,同一个按钮按两次不会有任何效果,因此每个按钮最多的操作次数只能为1。不妨用数组status[n+2]表示按钮的状态,result[n+2]表示期望的目标状态,元素的取值限定为0和1,那么status[i]的翻转会导致status[i-1]和status[i+1]都发生翻转。我们注意到,一旦status[i]发生了改变,由于会波及到status[i+1],所以status[i+1]是否发生改变也被固定死了。由此,我们得到下列解题思路:设置第一个按钮的状态不发生翻转,对比status和result的值,求得操作次数;然后设置第一个按钮的状态发生翻转,再求得操作次数。取次数少者作为输出结果,如果两种操作都不成功,则输出impossible。

在做题时发现一个巨坑,翻转状态时使用非运算~一直不成功,本地DeBug发现~0的结果居然等于-1,后面翻转状态修改为当前位和1进行异或运算,终于成功AC!

#include <bits/stdc++.h>
using namespace std;

// 重新设计
int main(void) {
    char line[30]; // input buffer
    cin >> line;
    const int N = strlen(line); // length of input string
    int oriLock[N];
    for (int i = 0; i < N; ++i) {
        oriLock[i] = line[i] - '0';
    }
    cin >> line;
    int destLock[N]; // get dest lock
    for (int i = 0; i < N; ++i) {
        destLock[i] = line[i] - '0';
    }
    
    // process corner case
    if (1 == N) {
        cout << ((oriLock[0] == destLock[0]) ? 0 : 1);
        return 0;
    }
    
    int result = INT_MAX;
    // process normal case
    for (int i = 0; i < 2; ++i) {
        int lock[N];
        for (int j = 0; j < N; ++j) {
            lock[j] = oriLock[j];
        }
        int count = 0; 
        // flip power0
        if (1 == i) {
            count = 1; // flip 1 time
            lock[0] ^= 1;
            lock[1] ^= 1;
        }
        for (int idx = 1; idx <= N - 1; ++idx) {
            // according to destLock to decide lock
            if (lock[idx -1] != destLock[idx - 1]) {
                ++count;
                lock[idx - 1] ^= 1;
                lock[idx] ^= 1;
                if (N - 1 != idx) {
                    lock[idx + 1] ^= 1;
                } 
            }
            if (N - 1 == idx && lock[idx] == destLock[idx]) {
                result = min(result, count);
            }
        }
    }
    
    if (result != INT_MAX) {
        cout << result;
    } else {
        cout << "impossible";
    }
    
    return 0;
} 

 

 


 

posted @ 2018-07-05 08:13  NaiveCoder  阅读(454)  评论(0)    收藏  举报