题意就是有个4*4的棋盘,上面有黑白两面的棋子,然后你可以选一个点,翻转这个点及他上下左右的棋子(如果有的话),求最小步数可以翻成全白或全黑,如果无法成功输出impossible。
如果是最少步数的话应该用到广搜,因为一个棋子只有正反两面,所以可以用二进制的形式存储棋盘的状态,参考了某大牛的代码,没有明显的用到DFS,但和DFS的效果是一样的,而且这样也使得代码变短了好多。
//poj 1753
//2013-10-16-21.35
#include <stdio.h>
int ans;
int cnt;
void search(int x, int sta, int cnt)
{
if (sta == 65535 || sta == 0)
{
if (cnt < ans)
ans = cnt;
return ;
}
if (cnt >= ans)
return ;
if (x == 17)
return ;
search(x+1, sta, cnt);
sta ^= (1<<((17-x)-1));//改变自己
if(x%4 != 0)
sta ^= (1<<((17-x-1)-1));//改变右边的
if(x%4 != 1)
sta ^= (1<<((17-x+1)-1));//改变左边的
if(x>4) sta ^= (1<<((17-x+4)-1));//改变上面的
if(x<=12) sta ^= (1<<((17-x-4)-1));//改变下面的
search(x+1, sta, cnt+1);
}
int main()
{
int sta = 0;
char ch;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
scanf("%c", &ch);
if (ch == 'b')
sta |= (1<<(16-(i+1)*4+4-(j+1)));
}
getchar();
}
ans = 999999;
search(1, sta, 0);
if (ans == 999999)
puts("Impossible");
else
printf("%d\n", ans);
return 0;
}