题目见:http://noi.openjudge.cn/ch0201/755/
最多翻转15次,所以按次数遍历,对0,1,2…15次中的每一次调用play()
进行枚举,注意函数的返回条件以及回溯的处理。
#include <iostream>
#include <iomanip>
using namespace std;
char a[8][8];
int step;
bool flag;
bool isOver() {
char temp = a[0][0];
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (a[i][j] != temp)
return false;
}
}
return true;
}
void change(int m, int n) {
if (m < 0 || m > 3 || n < 0 || n > 3) return;
if (a[m][n] == 'b') a[m][n] = 'w';
else
a[m][n] = 'b';
return;
}
void flip(int m, int n) {
change(m, n);
change(m - 1, n);
change(m + 1, n);
change(m, n - 1);
change(m, n + 1);
return;
}
void play(int m, int n, int deep) {
if (deep == step) {
flag = isOver();
return;
}
if (flag || m > 3)
return;
flip(m, n);
if (n < 3)
play(m, n + 1, deep + 1);
else
play(m + 1, 0, deep + 1);
flip(m, n);
if (n < 3)
play(m, n + 1, deep);
else
play(m + 1, 0, deep);
return;
}
int main() {
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
cin >> a[i][j];
flag = false;
for (step = 0; step < 16; step++) {
play(0, 0, 0);
if (flag == true)
break;
}
if (flag == true)
cout << step << endl;
else
cout << "Impossible" << endl;
//system("pause");
return 0;
}