CH0201 奇怪的开关 【二进制,枚举】

当上一行的开关方法确定时,如果上一行灯是关的,本行同列的灯就要打开,如果上一行灯是开的,本行同列的灯就不能打开。先确定第一行,剩下的方法唯一。

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

const int N = 5 + 5;
const int INF = 0x3f3f3f3f;

int T, n = 5, G[N][N], turn[N][N];

bool in_map (int x, int y) {
    return 1 <= x && x <= 5 && 1 <= y && y <= 5;
}

int sumX (int x, int y) {
    int ret = G[x][y] ^ turn[x][y];
    if (in_map (x - 1, y)) ret ^= turn[x - 1][y];
    if (in_map (x, y - 1)) ret ^= turn[x][y - 1];
    if (in_map (x, y + 1)) ret ^= turn[x][y + 1];
    return ret;
}

bool can_use (int fst) {
    // if (fst == 16) cout << "fst = " << fst << endl;
    memset (turn, 0, sizeof (turn));
    for (int i = 1; i <= 5; ++i) {
        turn[1][i] = (fst >> (i - 1)) & 1;  
        // if (fst == 16) cout << "turn[1][" << i << "] = " << turn[1][i] << endl; 
    }
    for (int i = 2; i <= 5; ++i) {
        for (int j = 1; j <= 5; ++j) {
            // if (fst == 16) {
            //     cout << "i = " << i << ", j = " << j << ", sumX = " << sumX(i - 1, j) << endl;
            // }
            if (sumX (i - 1, j) == 0) {
                turn[i][j] = 1;
            }
        }
    }
    for (int i = 1; i <= 5; ++i) {
        if (sumX (5, i) == 0) return false;
    }
    return true;
}

int get_ans () {
    int ret = 0;
    for (int i = 1; i <= 5; ++i) {
        for (int j = 1; j <= 5; ++j) {
            ret += turn[i][j];
        }
    }
    return ret;
}

int solve () {
    int ret = INF;
    for (int i = 0; i < 1 << 5; ++i) {
        if (can_use (i)) {
            // cout << "can_use" << endl;
            ret = min (ret, get_ans ());
        }
    }
    // cout << "ret = " << ret << endl;
    return ret > 6 ? -1 : ret;
}

int main () {
    freopen ("data.in", "r", stdin);
    // freopen ("data.out", "w", stdout);
    cin >> T;
    while (T--) {
        for (int i = 1; i <= 5; ++i) {
            for (int j = 1; j <= 5; ++j) {
                char _ch;
                scanf (" %c", &_ch);
                G[i][j] = (int)_ch - (int)'0';
            }
        }
        cout << solve () << endl;
    }
}
原文地址:https://www.cnblogs.com/maomao9173/p/13784481.html