对于此题,有三种解法。
第一是直接采用dfs进行搜索;
第二是采用状态压缩+bfs,以位来表示每个棋的状态
第三是采用高斯消元(之后补充)
/**
* @author johnsondu
* @time 2015.08.25 09:07
* @strategy dfs version
* @description using dfs to direct search
* @url http://poj.org/problem?id=1753
*/
#include <iostream>
#include <cmath>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#include <stack>
#include <cstdio>
#include <algorithm>
#include <set>
using namespace std;
int chess[4][4];
int res = 33;
void build()
{
char c;
for(int i = 0; i < 4; i ++)
for(int j = 0; j < 4; j ++)
{
cin >> c;
if(c == 'w') chess[i][j] = 0;
else chess[i][j] = 1;
}
}
void turn(int x, int y)
{
if(x < 4 && y < 4 && x >= 0 && y >= 0)
{
chess[x][y] = 1 - chess[x][y];
}
}
int done()
{
int s1 = 0;
for(int i = 0; i < 4; i ++)
for(int j = 0; j < 4; j ++)
s1 += chess[i][j];
if(s1 % 16)
return 0;
return 1;
}
void flip(int s)
{
int i = s / 4;
int j = s % 4;
turn(i, j);
turn(i + 1, j);
turn(i, j + 1);
turn(i - 1, j);
turn(i, j - 1);
}
void dfs(int s, int b)
{
if(done()){
if(res > b)
res = b;
return ;
}
if(s >= 16) return ;
dfs(s + 1, b);
flip(s);
dfs(s+1, b+1);
flip(s);
}
int main()
{
build();
dfs(0, 0);
if(res == 33)
printf("Impossible\n");
else printf("%d\n", res);
return 0;
}
/**
* @author johnsondu
* @time 2015.08.25 09:07
* @strategy state compress + bfs version
* @description using binary code to represent the state
* @url http://poj.org/problem?id=1753
*/
#include <iostream>
#include <cmath>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#include <stack>
#include <cstdio>
#include <algorithm>
#include <set>
using namespace std;
const int MAXN = 70000;
bool mark[MAXN];
typedef pair<int, int> pii;
int state_change(int state, int x)
{
state ^= (1 << x);
if(x + 4 < 16) state ^= (1 << (x + 4));
if(x - 4 >= 0) state ^= (1 << (x - 4));
if(x % 4< 3 && x + 1 < 16) state ^= (1 << (x + 1));
if(x % 4 > 0 && x - 1 >= 0) state ^= (1 << (x - 1));
return state;
}
int solve(int state)
{
queue<pii> q;
if(state == 0 || state == 65535) return 0;
q.push(make_pair(state, 0));
while(!q.empty()) {
state = q.front().first;
int t = q.front().second;
q.pop();
for(int i = 0; i < 16; i ++) {
int now = state_change(state, i);
if(now == 0 || now == 65535)
return t + 1;
if(!mark[now]) {
mark[now] = true;
q.push(make_pair(now, t + 1));
}
}
}
return -1;
}
int main()
{
int state;
char str[10];
memset(mark, false, sizeof(mark));
state = 0;
for(int i = 0; i < 4; i ++) {
scanf("%s", str);
for(int j = 0; j < 4; j ++) {
if(str[j] == 'b') state = state | (1 << (i * 4 + j));
}
}
mark[state] = true;
int ans = solve(state);
if(ans == -1) printf("Impossible\n");
else printf("%d\n", ans);
return 0;
}