HDOJ 1254 推箱子 (BFS)

来源:互联网 发布:伦.拜亚斯 大学数据 编辑:程序博客网 时间:2024/05/30 04:06

http://acm.hdu.edu.cn/showproblem.php?pid=1254

题意:推箱子游戏,在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,求最少的推箱子的次数,如果不能完成则输出-1。

思路:带嵌套的BFS~第一层BFS箱子,箱子每次移动前要再BFS一下人,看人能不能走到推动箱子的位置。

注意://因为人的位置不同时箱子可能可以到同一个位置两次,所以开4维(两维是箱子位置,两维是人的位置)数组标记。

#include<cstdio>#include<cstring>#include<queue> using namespace std; struct node{int x,y,cnt;int px,py;}now,tmp,pnow,ptmp; queue<struct node>q;//BFS箱子的队列queue<struct node>p;//BFS人的队列 int m,n;int maze[11][11];bool vis[11][11][11][11];bool pvis[11][11]; int dx[]={0,0,1,-1};int dy[]={1,-1,0,0}; bool p_ok(){if(ptmp.x>=0&&ptmp.y>=0&&ptmp.x<m&&ptmp.y<n&&maze[ptmp.x][ptmp.y]!=1&&!(ptmp.x==now.x&&ptmp.y==now.y)&&!pvis[ptmp.x][ptmp.y])return true;elsereturn false;} bool p_bfs(int k)//简单的BFS,i为箱子要去的方向{while(!p.empty())p.pop();memset(pvis,false,sizeof(pvis));pnow.x=tmp.px;pnow.y=tmp.py;if(pnow.x==now.x-dx[k]&&pnow.y==now.y-dy[k])//特殊判断人就在箱子边上且正好是要推箱子的位置的情况return true;pvis[pnow.x][pnow.y]=true;p.push(pnow);while(!p.empty()){pnow=p.front();p.pop();for(int i=0;i<4;i++){ptmp=pnow;ptmp.x+=dx[i];ptmp.y+=dy[i];if(p_ok()){if(ptmp.x==now.x-dx[k]&&ptmp.y==now.y-dy[k])return true;pvis[ptmp.x][ptmp.y]=true;p.push(ptmp);}}}return false;} bool ok(){if(tmp.x>=0&&tmp.y>=0&&tmp.x<m&&tmp.y<n&&maze[tmp.x][tmp.y]!=1&&!vis[tmp.x][tmp.y][tmp.px][tmp.py])return true;elsereturn false;} int bfs(){while(!q.empty())q.pop();now.cnt=0;vis[now.x][now.y][now.px][now.py]=true;q.push(now);while(!q.empty()){now=q.front();q.pop();for(int i=0;i<4;i++){tmp=now;tmp.x+=dx[i];tmp.y+=dy[i];if(ok()){if(p_bfs(i))//判断人能否走到要推箱子的位置{tmp.cnt++;if(maze[tmp.x][tmp.y]==3)return tmp.cnt;tmp.px=now.x;tmp.py=now.y;vis[tmp.x][tmp.y][now.px][now.py]=true;q.push(tmp);}}}}return -1;} int main(){int t;while(scanf("%d",&t)==1){while(t--){memset(vis,false,sizeof(vis));scanf("%d %d",&m,&n);for(int i=0;i<m;i++){for(int j=0;j<n;j++){scanf("%d",&maze[i][j]);if(maze[i][j]==2){now.x=i;now.y=j;}else if(maze[i][j]==4){now.px=i;now.py=j;}//初始化BFS箱子的第一个节点}}printf("%d\n",bfs());}}return 0;}



知识共享许可协议
作品sdc1992创作,采用知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议进行许可。

基于http://www.sdc1992.com/上的作品创作。

欢迎关注我的新博客:http://www.sdc1992.com/

原创粉丝点击