poj 1753 Flip Game

//题意:在一个4*4的棋盘上翻转棋子,棋子只有黑白两色,翻转了一个棋子以后,他的上下左右四个方向的棋子都得跟着变色,
//最后使得棋盘上所有的棋子都是白色,或者都是黑色。统计最少需要翻转棋子的个数。

#include<iostream> //bfs+位运算 参照 poj8 1166 The Clocks
#include <stdio.h>

using namespace std;
const int mod=0x55555555; //mod=(0101 0101 0101 0101 0101 0101 0101 0101)十六进制,实际上是16,4*4个 01
int fac[4][4]={{1,4,16,64},{256,1024,4096,16384},{65536,262144,1048576,4194304},{16777216,67108864,268435456,1073741824}};

int q[10000],dis[10000];
int dx[]={0,-1,0,1,0},dy[]={0,0,1,0,-1};
bool vis[mod]; //int 空间不够

int main()
{
int num=0;
char ch[5];
for(int i=0;i<4;++i)
{
scanf("%s",ch);
for(int j=0;j<4;++j)
if(ch[j]=='b')
num+=fac[i][j];
}
q[0]=num;
vis[num]=true;
dis[0]=0;
int front=0,rear=1,ok=0;
while(front<rear)
{
if(q[front]==0 || q[front]==mod)
{
printf("%d\n",dis[front]);
ok=1;
break;
}
for(int i=0;i<4;++i)
for(int j=0;j<4;++j) //翻转棋子[i][j]
{

int t=q[front];
for(int k=0;k<5;++k)
{
int newi=i+dx[k],newj=j+dy[k];
if(newi>=0&&newi<4&&newj>=0&&newj<4)
{
t += fac[newi][newj];
t = t & mod;
}
}
if(vis[t])
continue;
vis[t]=true;
dis[rear]=dis[front]+1;
q[rear++]=t;
}
front++;
}
if(!ok)
printf("Impossible\n");
return 0;
}

posted on 2011-07-22 20:26  sysu_mjc  阅读(164)  评论(0编辑  收藏  举报

导航