反转题的开关问题都很有意思!(前提是我做得出的….)
有一个4*4的矩阵,通过翻转使它的颜色一致,求最小的步数。
一开始以为全为黑色,GG…..
枚举第一行的反转状态就行啊。
#include <cstdio>
#include <cstring>
const int dx[5] = {-1, 0, 0, 0, 1};
const int dy[5] = {0, -1, 0, 1, 0};
char map[6][6];
char flip[6][6];
int ans = 25;
//判断是否为黑色
inline int get(int x, int y) {
int c = map[x][y];
for (int d= 0; d < 5; d++) {
int nx = x + dx[d];
int ny = y + dy[d];
if (nx >= 0 && nx < 4 && ny >= 0 && ny < 4) {
c += flip[nx][ny];
}
}
return c & 1;
}
void f(int color) {
for (int x = 1; x < 4; x++) {
for (int y = 0; y < 4; y++) {
if (get(x - 1, y) == color) {
flip[x][y] = 1;
}
}
}
bool ok = true;
for (int j = 0; j < 4; j++) {
if (get(3, j) == color) {
ok = false;
break;
}
}
if (ok) {
int cnt = 0;
for (int x = 0; x < 4; x++) {
for (int y = 0; y < 4; y++) {
cnt += flip[x][y];
}
}
ans = ans > cnt ? cnt : ans;
}
}
int main(int argc, char const *argv[]) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
int ch = getchar();
map[i][j] = (ch == 'w') ? 0 : 1;
}
getchar();
}
for (int i = 0; i < 1 << 4; i++) {
memset(flip, 0, sizeof(flip));
for (int j = 0; j < 4; j++) {
flip[0][4-j-1] = i >> j & 1;
}
f(0);
}
for (int i = 0; i < 1 << 4; i++) {
memset(flip, 0, sizeof(flip));
for (int j = 0; j < 4; j++) {
flip[0][4-j-1] = i >> j & 1;
}
f(1);
}
if (ans == 25) {
puts("Impossible");
} else {
printf("%d\n", ans);
}
return 0;
}