深搜,直接上代码
#include<iostream>
#include<cstdio>
using namespace std;
int board[4][4];
int c = 17; // 操作的最大数
void read() { // 读入一个棋盘
char c;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
cin >> c;
if (c == 'w')
board[i][j] = 0;
else
board[i][j] = 1;
}
}
}
void turn(int x, int y) { // 翻转当前位置的棋盘
if (x >= 0 && x < 4 && y >= 0 && y < 4)
board[x][y] = !board[x][y];
}
void flip(int pos) { // 翻转自身及周围
int i = pos / 4;
int j = pos % 4;
turn(i, j);
turn(i, j + 1);
turn(i, j - 1);
turn(i + 1, j);
turn(i - 1, j);
}
int finish() { // 判断是否全黑或全白
int sum = 0;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
sum += board[i][j];
}
}
if (sum % 16)
return 0;
else
return 1;
}
void DFS(int pos, int num) { // 深搜
if (finish()) {
if (c > num) { // 如果步数更少,则保存
c = num;
}
return;
}
if (pos >= 16) // 如果已经遍历完,则无结果,注意终止条件为pos,而非num
return;
DFS(pos + 1, num); // 不翻转当前格子,对下一个进行操作
flip(pos); // 翻转当前格子
DFS(pos + 1, num + 1); // 对下一个进行操作
flip(pos); // 复原当前格子
}
int main() {
read();
DFS(0, 0);
if (c == 17)
printf("Impossible\n");
else
printf("%d\n", c);
}