题意:给出 4x4 的棋盘,只有白棋和黑棋,每一步可以选中一颗棋子翻转本身及相邻棋子,问能不能达到全黑或全白的状态?如果能,输出步数,否则输出 Impossible
分析:4x4的棋盘,直接用16位整数保存整个棋盘的状态然后 BFS 就好了
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int inf = 0x3f3f3f3f;
const int STAN = 70000;
int step[STAN], dx[] = {0,0,-1,1}, dy[] = {-1,1,0,0};
int encode(int board[4][4]) {
int sta = 0;
for(int i = 3; i >= 0; i--)
for(int j = 3; j >= 0; j--)
sta = sta << 1 | board[i][j];
return sta;
}
void decode(int s, int board[4][4]) {
for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++) {
board[i][j] = s & 1;
s >>= 1;
}
}
void solve(int s) {
queue <int> q;
int board[4][4], tmpboard[4][4];
memset(step, inf, sizeof(step));
q.push(s);
step[s] = 0;
while(!q.empty()) {
s = q.front();
q.pop();
decode(s, board);
for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++) {
memcpy(tmpboard, board, sizeof(board));
board[i][j] = !board[i][j];
for(int k = 0, x = i, y = j; k < 4; k++, x = i, y = j) {
x += dx[k];
y += dy[k];
if(x >=0 && x < 4 && y >= 0 && y < 4)
board[x][y] = !board[x][y];
}
int ns = encode(board);
if(step[ns] > step[s] + 1) {
step[ns] = step[s] + 1;
q.push(ns);
}
memcpy(board, tmpboard, sizeof(tmpboard));
}
}
int ans = min(step[0], step[(1 << 16) - 1]);
if(ans == inf)
puts("Impossible");
else
printf("%d\n", ans);
}
int input() {
int sta = 0;
char line[5];
for(int i = 0; i < 4; i++) {
if(scanf("%s", line) == EOF)
exit(0);
for(int j = 0; j < 4; j++) {
if(line[j] == 'b')
sta |= 1 << ((i << 2) + j);
}
}
return sta;
}
int main() {
solve(input());
return 0;
}