您的位置:首页 > 其它

poj1753——Flip Game

2010-12-14 14:55 519 查看
题意:给你一张有黑白棋子的图,要求通过最少的步骤将棋盘上的棋子翻成同一颜色。

思路:用二进制表示黑白棋子,然后根据sum=g[0][0]*2^0+g[0][1]*2^1+g[0][2]*2^2......+g[3][3]*2^15,如此来记录状态,然后开始广搜工作:每次取出队列里的一个sum,求sum的二进制数,还原成一张图,然后一个个改变状态,看是否满足入队要求!

PS:((d^1)-d)其中的(d^1)记得加括号,否则你有可能杯具很久!

#include<cstdio>
#include<iostream>
using namespace std;
char g[5][5];
bool vis[70000];
int gg[5][5];
int dir[][2]={{0,-1},{0,1},{-1,0},{1,0}};
int f[5][5];
struct node
{
int step;
int num;
}queue[70000];
void solve()
{
int i,j,sum=0,d=1,front=0,rear=0;
memset(vis,true,sizeof(vis));
for(i=0;i<4;i++)
for(j=0;j<4;j++)
{
f[i][j]=d;
sum+=d*gg[i][j];
d*=2;
}
rear++;queue[rear].step =0;
queue[rear].num =sum;
vis[sum]=false;
while(rear!=front)
{
front++;
const struct node temp=queue[front];
if(temp.num ==0||temp.num ==65535)
{
printf("%d/n",temp.step );
return ;
}
d=temp.num ;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
{
gg[i][j]=d%2;
d/=2;
}
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
d=gg[i][j];
sum=0;
sum+=((d^1)-d)*f[i][j];
for(int k=0;k<4;k++)
{
int tempx=i+dir[k][0];
int tempy=j+dir[k][1];
if(tempx>=0&&tempx<4&&tempy>=0&&tempy<4)
{
d=gg[tempx][tempy];
sum+=((d^1)-d)*f[tempx][tempy];
}
}
if(temp.num +sum>=0&&vis[temp.num +sum])
{
rear++;
queue[rear].num =temp.num +sum;
queue[rear].step =temp.step +1;
vis[temp.num +sum]=false;
}
}
}
}
printf("Impossible/n");
}
int main()
{
int i,j;
for(i=0;i<4;i++)
scanf("%s",&g[i]);
for(i=0;i<4;i++)
for(j=0;j<4;j++)
{
if(g[i][j]=='b')
gg[i][j]=1;
else gg[i][j]=0;
}
solve();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: