传送门:http://poj.org/problem?id=1753
题意比较简单,就是反转一块,同时会反转四周的块,问几步能最少反转,因为一共就16块,所以表示出所有状态也就是1<<16种,直接暴力就可以了。
代码:
<span style="font-size:14px;">#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<time.h>
#include<vector>
#include<string>
#include<queue>
#include<map>
#include<set>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
#define ff(x) x=(x=='b'?'w':'b');
char pic[10][10];
char s[5][5];
int ans;
bool check()
{
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
if (s[i][j] != s[0][0])
return false;
return true;
}
inline bool judge(int x,int y){return x >= 0 && x < 4 && y >= 0 && y < 4;}
void flip(int x,int y)
{
ff(s[x][y]);
if (judge(x + 1, y)) ff(s[x + 1][y]);
if (judge(x - 1, y)) ff(s[x - 1][y]);
if (judge(x, y + 1)) ff(s[x][y + 1]);
if (judge(x, y - 1)) ff(s[x][y - 1]);
}
bool trys(int n)
{
int cnt = 0;
int i, j;
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
s[i][j] = pic[i][j];
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
if (n&(1 << (i * 4 + j)))
cnt++, flip(i, j);
if (check())
{
ans = min(ans, cnt);
return true;
}
return false;
}
int main()
{
// freopen("D://input.txt", "r", stdin);
// freopen("D://output.txt", "w", stdout);
while (scanf("%s", pic[0]) != EOF)
{
ans = 100;
bool ok = false;
int i, j;
for (i = 1; i < 4; i++)
scanf("%s", pic[i]);
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
s[i][j] = pic[i][j];
if (check())
{
printf("0\n");
continue;
}
int all = (1 << 16);
for (i = 1; i <= all; i++) {//(1<<16)是反转最后一块,其他都不反转,因为没写等号wa了很久
ok = trys(i) || ok;
}
if (ok) printf("%d\n", ans);
else printf("Impossible\n");
}
// printf("%.6f\n", (double)clock() / CLOCKS_PER_SEC);
return 0;
}
</span>