| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 28190 | Accepted: 12221 |
Description
Consider the following position as an example:
Input
Output
Sample Input
bwwb bbwb bwwb bwww
Sample Output
4
主要用位运算和(优先)队列搜索,每个格子有两种状态,则共有2^16=65536;
每个棋子有两个状态可以用二进制表示,如黑为1,白为0;
由位运算规则:1^1=0,0^1=1;
对16个格子进行翻转操作有16种方式,
可以令一些格子为1,另一些为0来模拟;
1100
1000
0000
0000
转换成十进制为2^15+2^14+2^11=51200,
即16个十进制数存入change[]数组;
搜索过程中每个出现的状态都会被标记,再出队,因此,不会出现死循环。
具体代码如下:
#include"stdio.h"
#include"iostream"
#include"queue"
using namespace std;
#define N 65536
int dir[4][2]={1,0,-1,0,0,-1,0,1};
int change[16];
int visit[N];
struct node // 用优先队列,一般队列也能过
{
int state,step;
friend bool operator<(node a,node b)
{
return a.step>b.step;
}
};
void inti() //若提前求出16个操作状态存入数组可以省去该函数
{
int i,j,x,y,t,temp,k=0;
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
temp=0;
temp^=(1<<((3-i)*4+3-j));
for(t=0;t<4;t++)
{
x=dir[t][0]+i;
y=dir[t][1]+j;
if(x<0||y<0||x>3||y>3)
continue;
temp^=(1<<((3-x)*4+3-y));
}
change[k++]=temp;
}
}
}
int bfs(int t)
{
int i;
memset(visit,0,sizeof(visit));
priority_queue<node>q;
node cur,next;
cur.state=t;
cur.step=0;
q.push(cur);
visit[t]=1;
while(!q.empty())
{
cur=q.top();
q.pop();
if(cur.state==0||cur.state==N-1)
return cur.step;
for(i=0;i<16;i++)
{
next.state=cur.state^change[i];
next.step=cur.step+1;
if(!visit[next.state])
{
q.push(next);
visit[next.state]=1;
}
}
}
return -1;
}
int main()
{
int i,j,t,ans;
inti();
char chess[5][5];
while(scanf("%s",chess[0])!=-1)
{
for(i=1;i<4;i++)
scanf("%s",chess[i]);
t=0;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
{
if(chess[i][j]==‘b‘)
t^=1<<((3-i)*4+3-j); //此处把异或改为加也行,
}
ans=bfs(t);
if(ans==-1)
printf("Impossible\n");
else
printf("%d\n",ans);
}
return 0;
}
poj 1753 Flip Game,布布扣,bubuko.com
原文:http://blog.csdn.net/u011721440/article/details/22093997