cdoj 1488 flip game解题报告

ALGORITHM ANALYSE:bfs+位运算
//每个方格里的棋子只有两种状态,因此可用0,1表示,而整个棋盘则可以表示为一个十六位的二进制整数
//若要对某个位置做翻转操作,可对整数进行异或操作,棋盘上每个位置上的翻转二进制数是可以预先求得的
//bfs对每个位置进行翻转,因为整个棋盘只有十六个位置,因此所有的状态是不超过2^16的,对每个扩展进行标记后可以避免重复的状态
//因为状态是有限的,因此队列可以为空
CODE:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int myqueue[500000],step[500000],qback=0,qfront=0;
int flag[500000],turn[20];
int main()
{
int i,j,ini=0; char ch;
char str[5][6];
for(i=15;i>=0;i--)
{
turn[i]=(1<<i);
if(i<12) turn[i]+=(1<<(i+4));
if(i%4!=3) turn[i]+=(1<<(i+1));
if(i%4!=0) turn[i]+=(1<<(i-1));
if(i>3) turn[i]+=(1<<(i-4));
}
for(i=0;i<4;i++) scanf("%s",str[i]);
for(i=0;i<4;i++)
for(j=0;j<4;j++) if(str[i][j]=='b') ini+=(1<<(15-(4*i)-j));
memset(flag,0,70000);
flag[ini]=1; myqueue[0]=ini; step[0]=0; qback++;
while(qfront!=qback)
{
if(myqueue[qfront]==0 || myqueue[qfront]==65535) { printf("%d",step[qfront]); return 0; }
else
{
int temp;
for(i=15;i>=0;i--)
{
temp=myqueue[qfront]^turn[i];
if(flag[temp]==0)
{
flag[temp]=1;
myqueue[qback]=temp; step[qback]=step[qfront]+1;
qback++;
}
}
}
qfront++;
}
printf("Impossible");
return 0;
}

//这道题目的精髓在于位运算,通过异或符号快速度的对相关位置进行取反操作,使得队列中的元素只是一个整数

 

posted on 2013-05-17 00:29  uestc小田  阅读(173)  评论(0编辑  收藏  举报

导航