#include using namespace std; const int INF = 0x3f3f3f3f; const int N = 6; // char 数组版本 char g[N][N], bg[N][N]; // 工作的临时数组 和 原始状态数组 // 上右下左中 int dx[] = {-1, 0, 1, 0, 0}; int dy[] = {0, 1, 0, -1, 0}; // 按一下第x行第y列的开关 void turn(int x, int y) { for (int i = 0; i < 5; i++) { int tx = x + dx[i], ty = y + dy[i]; if (tx < 0 || tx >= 5 || ty < 0 || ty >= 5) continue; g[tx][ty] ^= 1; //'0':48 '1':49 // (48)_{10}=(110000)_{2} (49)_{10}=(110001)_{2} // 由于48的最后一位是0,而49最后一位是1,所以,异或就可以实现两者之间的切换,真是太神奇了~ } } int main() { int T; cin >> T; while (T--) { // 按一行的字符串读取 for (int i = 0; i < 5; i++) cin >> bg[i]; // 原来的字符状态数组 // 预求最小,先设最大 int res = INF; // 枚举所有可能的操作办法:00000,00001,00010,...,11111,共32种办法 for (int op = 0; op < (2 << 5); op++) { int cnt = 0; memcpy(g, bg, sizeof g); // 将原始状态复制出一份放入g数组,开始尝试 // 操作办法op,共5位,1代表修改,0代表不改,按二进制由右到左可以枚举出这种操作需要改哪几列 for (int i = 0; i < 5; i++) if (op >> i & 1) { turn(0, i); // 你想改就改吧~ cnt++; } // 第二行需要观察第一行,啊~我同位的上一行有一个0!这可是大事,因为我必须补上它,否则就没有人可以补上它了~ for (int i = 0; i < 4; i++) for (int j = 0; j < 5; j++) if (g[i][j] == '0') { turn(i + 1, j); // i+1行必须按下按钮 cnt++; } // 检查最后一行灯是否全亮.因为如果它还有0存在,就没机会补全了 bool success = true; for (int i = 0; i < 5; i++) if (g[4][i] == '0') success = false; if (success) res = min(res, cnt); // 如果成功全亮,那你是多少步呢? } // 题意要求,大于6次,算失败 if (res > 6) res = -1; cout << res << endl; } return 0; }