POJ 1753
思路:对于每个棋子有翻和不翻两种状态,翻奇数次等于翻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; }