Files
python/TangDou/AcWing_TiGao/T6/DiTuiDiGui/95_DiTui.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

66 lines
2.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <bits/stdc++.h>
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;
}