Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 28190 | Accepted: 12221 |
Description
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