POJ 1753 Flip Game 状态压缩+枚举,bfs
http://poj.org/problem?id=1753
题意:四行四列的格子里放 黑色和白色的双面 卡片,然后反转卡片(黑->白or 白->黑),同时这张卡片的四周(上 下 左 右)也要反转),到全为 白色或黑色为止,
问最少要几步,如果达不到目的输出“Impossible"
状态压缩+枚举 ,bfs 最少步数 bfs求
黑色和白色分别用0 1 表示 涉及到位运算 抑或
枚举的是状态0~(1<<16-1)
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<queue>
using namespace std;
char a[18];
bool vis[1<<17]={0};
struct Node
{
int now;
long long step;
Node(int a,int b){now=a;step=b;}
};
int next(int x,int i)
{
x^=1<<i;
int a,b;
a=i/4;
b=i%4;
if(a-1>=0)x^=1<<(i-4);
if(a+1<=3)x^=1<<(i+4);
if(b-1>=0)x^=1<<(i-1);
if(b+1<=3)x^=1<<(i+1);
return x;
}
int bfs(int x)
{
int i;
queue<Node>qu;
qu.push(Node(x,0));
vis[x]=1;
while(!qu.empty())
{
Node t=qu.front();
qu.pop();
if(t.now==0||t.now==((1<<16)-1))
return t.step;
for(i=0;i<16;i++)
{
int d=next(t.now,i);
if(!vis[d])
{
qu.push(Node(d,t.step+1));
vis[d]=1;
}
}
}
return -1;
}
int main()
{
int i,Sum=0;
for(i=0;i<16;i++)
{
cin>>a[i];
if(a[i]=='b')
Sum+=1<<i;
}
long long ans=bfs(Sum);
if(ans==-1)
cout<<"Impossible\n";
else cout<<ans<<endl;
return 0;
}