这是一道二进制枚举题,我们可以发现第一行确定状态之后,我们可以根据第一行的状态来按第二行的,同理第二行第三行,所以可以考虑枚举第一行的状态,这里采用二进制枚举的方式,即0~2<<4,枚举到最后一行的时候,如果最后一行存在熄灭的点,就不是答案,总结一下,这题的思路就是通过枚举第一行的状态,右移几位是1则turn一下,从第二行开始,如果前一行这个位置是暗的,我们下一行这个位置就要turn一下,如此更新答案即可
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
const int ax[5] = {0, -1, 1, 0, 0};
const int ay[5] = {0, 0, 0, -1, 1};
char maze[10][10], back[10][10];
void turn(int x, int y) {
for(int i = 0; i < 5; i++) {
int tempx = x + ax[i];
int tempy = y + ay[i];
if(tempx >= 0 && tempx < 4 && tempy >= 0 && tempy < 4)
maze[tempx][tempy] ^= 1;
}
}
int solve() {
int ans = 0x3f3f3f3f;
for (int i = 0; i <= 2 << 4; ++i) {
memcpy(back, maze, sizeof maze);
int now = 0;
for (int j = 0; j < 4; ++j) {
if (i >> j & 1) {
now++;
turn(0, j);
}
}
for (int k = 0; k < 3; ++k)
for (int l = 0; l < 4; ++l)
if (maze[k][l] == '0') {
turn(k + 1, l);
now++;
}
int flag = 1;
for (int j = 0; j < 4; j++) {
if (maze[3][j] == '0') {
flag = 0;
break;
}
}
if (flag) ans = min(ans, now);
memcpy(maze, back, sizeof back);
}
return ans;
}
int main() {
for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++) {
char c;
cin >> c;
if(c == 'w') maze[i][j] = '0';
else maze[i][j] = '1';
}
int ans = solve();
for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++)
if(maze[i][j] == '0') maze[i][j] = '1';
else maze[i][j] = '0';
ans = min(ans, solve());
if(ans == 0x3f3f3f3f) puts("Impossible");
else printf("%d\n", ans);
return 0;
}