您的位置:首页 > 其它

POJ 1753 Flip Game

2011-07-16 17:17 288 查看
状态压缩+广搜就可以了.

用0表示w,1表示b,16位2进制最大是65535.也就是说全黑或全白的状态是0和65535.

接下来广搜就可以了

一开始大于等于号忘了写等于号导致WA了好几次..囧..

#include <cstdio>
#include <queue>
#include <string.h>
using namespace std;
int vi[65536];
int f(int s,int j){
//1 xor 0 =1,1 xor 1 = 0 状态改变
//0 xor 0 =0,0 xor 1 = 1 状态不变
s^=(1<<j);
if(j/4!=0)s^=1<<(j-4);//不是第一行
if(j/4!=3)s^=1<<(j+4);//不是最后一行
if(j%4!=0)s^=1<<(j-1);//不是第一列
if(j%4!=3)s^=1<<(j+1);//不是最后一列
return s;
}
int bfs(int x){
if(x==0||x==65535)return 0;//初始就已达到状态
queue<int> qu;
qu.push(x);
vi[x]=1;
int step=0;
int pos=0,epos=1;
while(1){
int s2=epos;
step++;
for(int i=pos;i<epos;i++){//遍历这一层
int s=qu.front();
qu.pop();
for(int j=0;j<16;j++){//16个灯
int next=f(s,j);
if(next==0||next==65535)return step;//达到状态
if(vi[next]==0){
vi[next]=1;
qu.push(next);
s2++;
}
}
}
if(pos==epos)return -1;//这一层便利中没有加入新状态,不能向下搜索了
pos=epos;
epos=s2;
}
return -1;
}
int main(){
char line[6];
int st=0,res;
memset(vi,0,sizeof(vi));
for(int i=0;i<4;i++){
scanf("%s",line);
for(int j=0;j<4;j++){
if(line[j]=='b')st+=1<<(4*i+j);
}
}
if((res=bfs(st))>=0)printf("%d\n",res);
else printf("Impossible\n");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: