95. 费解的开关

5 * 5 方阵,二进制枚举第一行的开关情况,后一行的开关情况由上一行的灯的亮暗情况决定,最后特判一下最后一行。所有开关次数取最小值,最后检查一下开关次数是否大于6就行了。

#include<iostream>
#include<cstring>

using namespace std;

const int N = 10;

int n;
int dx[] = {0, 1, 0, -1, 0}, dy[] = {0, 0, 1, 0, -1};
char g[N][N], backup[N][N];

void turn(int x, int y){
    for(int i = 0; i < 5; i ++){
        int a = x + dx[i], b = y + dy[i];
        if(a < 0 || a >= 5 || b < 0 || b >= 5) continue;
        g[a][b] ^= 1;
    }
}

int main(){
    cin >> n;
    
    while(n --){
        for(int i = 0; i < 5; i ++) cin >> g[i];
        
        int res = 10;
        
        memcpy(backup, g, sizeof g);
        
        for(int i = 0; i < 32; i ++){
            int step = 0;
            for(int j = 0; j < 5; j ++)
                if(i >> j & 1){
                    step ++;
                    turn(0, j);
                }
            
            for(int j = 1; j < 5; j ++)
                for(int k = 0; k < 5; k ++)
                    if(g[j - 1][k] == '0'){
                        step ++;
                        turn(j, k);
                    }
            
            int flag = 1;
            for(int j = 0; j < 5; j ++)
                if(g[4][j] == '0'){
                    flag = 0;
                    break;
                }
            
            if(flag) res = min(res, step);
            
            memcpy(g, backup, sizeof g);
        }
        
        if(res > 6) res = -1;
        
        cout << res << endl;
    }
    
    return 0;
}
posted @ 2020-08-03 21:50  yys_c  阅读(144)  评论(0编辑  收藏  举报