思路:对于每个棋子有翻和不翻两种状态,翻奇数次等于翻1次,翻偶数次等于翻0次,因此16个棋子就有2^16种翻转的状态,枚举每个状态得到最小解。可以事先将翻转每个棋子后对应的状态保存起来。
#include<iostream>
#include<cstdio>
using namespace std;
char s[5][5];
int st[16], ans = 17, all = 0;
int status[16]={0xC800, 0xE400, 0x7200, 0x3100,
0x8C80, 0x4E40, 0x2720, 0x1310,
0x08C8, 0X04E4, 0X0272, 0X0131,
0X008C, 0X004E, 0X0027, 0X0013};
void dfs(int id, int steps){
if(steps >= ans) return;
if(id >= 16){
if(all == 0 || all == 65535) ans = steps;
return;
}
dfs(id+1, steps);
all ^= status[id];
dfs(id+1, steps+1);
all ^= status[id];
}
int main(){
scanf("%s%s%s%s", s[3], s[2], s[1], s[0]);
for(int i = 0;i < 4;i ++)
for(int j = 0;j < 4;j ++)
if(s[i][j] == 'b') all ^= 1 << (i * 4 + j);
dfs(0, 0);
ans > 16 ? printf("Impossible") : printf("%d\n", ans);
return 0;
}