解题思路:每一行每一个开关是否需要操作完全由上一行灯的亮灭状态所决定。
所以用二进制枚举第一行开关的操作情况。
第一行灯的亮灭状态确定后,整个5*5所有灯的亮灭状态就确定了。
因为最后一行没有下一行了,所以判断最后一行是否全为亮,若不全为亮就是不合题意。
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 6; 4 char g[N][N], bk[N][N]; //g是原始的,bk是备份 5 int dx[5] = {-1, 0, 1, 0, 0}; 6 int dy[5] = {0, 1, 0, -1, 0}; //五个点 7 void turn(int x, int y) { 8 for (int i = 0; i < 5; i++) { 9 int a = x + dx[i]; 10 int b = y + dy[i]; 11 if (a < 0 || a >= 5 || b < 0 || b >= 5) { 12 continue; 13 } 14 if (g[a][b] == '0') { 15 g[a][b] = '1'; 16 } else { 17 g[a][b] = '0'; 18 } 19 } 20 } 21 int main() { 22 int T; 23 cin >> T; 24 while (T--) { 25 for (int i = 0; i < 5; i++) { 26 for (int j = 0; j < 5; j++) { 27 cin >> g[i][j]; 28 } 29 } 30 int res = 20; 31 for (int op = 0; op < (1 << 5); op++) { 32 memcpy(bk, g, sizeof g); //把g备份入bk中 33 int step = 0; //存储当前op这一方案的操作次数 34 for (int i = 0; i < 5; i++) { //操作第一行 35 if (op >> i & 1) { 36 step++; 37 turn(0, i); 38 } 39 } 40 for (int i = 0; i < 4; i++) { //再判断前4行 41 for (int j = 0; j < 5; j++) { 42 if (g[i][j] == '0') { 43 step++; 44 turn(i + 1, j); 45 } 46 } 47 } 48 bool is_ok = true; 49 for (int i = 0; i < 5; i++) { //判断第5行 50 if (g[4][i] == '0') { 51 is_ok = false; 52 break; 53 } 54 } 55 if (is_ok) { 56 res = min(res, step); 57 } 58 memcpy(g, bk, sizeof bk); //将g恢复原状 59 } 60 if (res > 6) { 61 res = -1; 62 } 63 cout << res << endl; 64 } 65 return 0; 66 }