Timus_1122_Game
题目大意:给出一个4×4的用黑白两色棋子覆盖的棋盘状态,以及选择任意某一棋子以其为中心进行翻转的一个3×3的01翻转规则,1为翻转,0则不翻转,问能否经过若干次操作,是的整个棋盘变成同一种颜色。
其实题目比较简单,类似的题也做过几道了。显然每个棋子以其为中心最多翻转一次。这样总共16个棋子也就是有2ˆ16种状态,然后就直接枚举每一种情况。然后我居然因为一个数组开小了,一直WA。最近真的脑子有点乱乱的=_=,刚才终于让我De完bug了,所以写写题解放松一下。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#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
int f[8][8] = {0}, a[8][8] = {0}, b[4][4] = {0};
int dx[4][4], dy[4][4];
bool check() {
int s = a[1][1];
for (int i = 1; i <= 4; i++)
for (int j = 1; j <= 4; j++)
if (a[i][j] != s) return false;
return true;
}
void convert(int x, int y) {
for (int i = 1; i <= 3; i++)
for (int j = 1; j <= 3; j++)
a[x+dx[i][j]][y+dy[i][j]] = a[x+dx[i][j]][y+dy[i][j]] ^ b[i][j];
}
void get() {
for (int i = 1; i <= 4; i++)
for (int j = 1; j <= 4; j++)
a[i][j] = f[i][j];
}
int main() {
char c;
memset(f, 0, sizeof(f));
for (int i = 1; i <= 3; i++) {
dy[i][1] = dx[1][i] = -1;
dy[i][2] = dx[2][i] = 0;
dy[i][3] = dx[3][i] = 1;
}
for (int i = 1; i <= 4; i++)
for (int j = 1; j <= 4; j++) {
cin >> c;
if (c == 'B') f[i][j] = 1;
}
for (int i = 1; i <= 3; i++)
for (int j = 1; j <= 3; j++) {
cin >> c;
b[i][j] = c - '0';
}
int ans = 1 << 17, x, y;
for (int i = 0; i < (1 << 16); i++) {
get();
int tmp = 0, k = i, bit = 1;
while (k) {
while (k % 2 == 0) {
bit++;
k /= 2;
}
x = (bit-1)/4 + 1;
y = (bit % 4 == 0) ? 4 : bit%4;
convert(x, y);
tmp++;
bit++;
k /= 2;
}
if (check()) ans = min(ans, tmp);
}
if (ans < (1 << 17)) cout << ans << endl;
else cout << "Impossible" << endl;
return 0;
}