poj1753——Flip Game

本文介绍了一种使用二进制表示和广度优先搜索解决黑白棋盘翻转问题的方法,目标是最少步骤将所有棋子变为同一颜色。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

思路:用二进制表示黑白棋子,然后根据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; }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值