除了第一行之外,每一行的操作都由上面一行决定。根据题目所给的限制可以知道,每一个开关只需要操作一次。如果每次从第一行开始操作,第一行的操作种类有$2^5$,那么下一行必须操作,也是只能操作的就是上一行对应列为暗的块。
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| #include <bits/stdc++.h> using namespace std; const int N = 6; int m[N][N], backup[N][N]; int dx[4]= {1, 0, -1, 0}; int dy[4] = {0, -1, 0, 1};
void p() { for(int i = 1; i <= 5; ++i){ for(int j = 1; j <= 5; ++j) { printf("%d", m[i][j]); } printf("\n"); } printf("\n"); }
void turn_on(int x, int y) { backup[x][y] ^= 1; for(int i = 0; i < 4; ++i) { int xx = x + dx[i], yy = y + dy[i]; if(xx >= 1 && xx <= 5 && yy >= 1 && yy <= 5) { backup[xx][yy] ^= 1; } } }
int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r", stdin); #endif int n; scanf("%d", &n); while(n--) { string s; for(int i = 1; i <= 5; ++i) { cin >> s; for(int j = 0; j < 5; ++j) { m[i][j+1] = s[j] - '0'; } } int res = 7; for(int i = 0; i < 32; ++i) { memcpy(backup, m, sizeof m); int times = 0; for(int j = 0; j < 5; ++j) { if((i >> j) & 1) { turn_on(1, j+1); times++; } } for(int j = 2; j <= 5; ++j) { for(int k = 1; k <= 5; ++k) { if(backup[j-1][k] == 0) { turn_on(j, k); times++; if(times > 6) break; } } if(times > 6) break; } bool flag = true; for(int i = 1; i <= 5; ++i) if(backup[5][i] == 0) { flag = false; break; } if(flag && times <= 6) res = min(res, times); }
if(res > 6) printf("-1\n"); else printf("%d\n", res); } return 0; }
|