简单的BFS,加上用位操作来定义和改写状态。ac时运行了100多ms,看discussion里面有人跑的很快,应该有更优化的方法吧,没细究了。
#include <cstdio> #include <queue> using namespace std; const int ROW = 4; const int ajacent[4][2] = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } }; struct Status{ int s; int step; }; int getStatus(char** board) { int ans = 0; for (int i = 0; i < ROW; i++){ for (int j = 0; j < ROW; j++){ ans <<= 1; if (board[i][j] == 'b'){ ans++; } } } return ans; } int main() { char* board[ROW]; bool visited[65536]; memset(visited, 0, sizeof(visited)); queue<Status> Q; for (int i = 0; i < ROW; i++){ board[i] = (char*)malloc(5 * sizeof(char)); } for (int i = 0; i < ROW; i++){ scanf("%s", board[i]); } Status tmpSt; tmpSt.s = getStatus(board); tmpSt.step = 0; Q.push(tmpSt); visited[tmpSt.s] = true; while (!Q.empty()){ Status current = Q.front(); if (current.s == 0 || current.s == 0xffff) break; for (int i = 0; i < ROW; i++){ for (int j = 0; j < ROW; j++){ int tmpS = current.s ^ (1 << (ROW * i + j)); for (int k = 0; k < 4; k++){ int tmpI = i + ajacent[k][0], tmpJ = j + ajacent[k][1]; if (tmpI >= 0 && tmpI < 4 && tmpJ >= 0 && tmpJ < 4){ tmpS ^= (1 << (ROW * tmpI + tmpJ)); } } if (!visited[tmpS]){ tmpSt.s = tmpS; tmpSt.step = current.step + 1; Q.push(tmpSt); visited[tmpS] = true; } } } Q.pop(); } if (!Q.empty()){ printf("%d ", Q.front().step); } else{ printf("Impossible "); } return 0; }