hdu 1254 推箱子【广度优先搜索】

推箱子

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5318    Accepted Submission(s): 1493


Problem Description
推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不能拉箱子,因此如果箱子被推到一个角上(如图2)那么箱子就不能再被移动了,如果箱子被推到一面墙上,那么箱子只能沿着墙移动.

现在给定房间的结构,箱子的位置,搬运工的位置和箱子要被推去的位置,请你计算出搬运工至少要推动箱子多少格.


 

Input
输入数据的第一行是一个整数T(1<=T<=20),代表测试数据的数量.然后是T组测试数据,每组测试数据的第一行是两个正整数M,N(2<=M,N<=7),代表房间的大小,然后是一个M行N列的矩阵,代表房间的布局,其中0代表空的地板,1代表墙,2代表箱子的起始位置,3代表箱子要被推去的位置,4代表搬运工的起始位置.
 

Output
对于每组测试数据,输出搬运工最少需要推动箱子多少格才能帮箱子推到指定位置,如果不能推到指定位置则输出-1.
 

Sample Input
  
  
1 5 5 0 3 0 0 0 1 0 1 4 0 0 0 1 0 0 1 0 2 0 0 0 0 0 0 0
 

Sample Output
  
  
4
分析:此题咋看不敢做,最后别人都做了,怕被碾压就现了一下做了,
此题是求箱子移动最小布数,这样就简单了,我们把重心移到箱子上,
求广搜箱子到终点的同时,因为只能推,再用广搜判断人是否能到推的
那个位置上,需要注意的是:标记数组要用三维,记录箱子的位置和在
此位置上的方向,因为箱子可以被推到以前走过的位置,只不过方向不同
,如用二维这只能记录路径,走过了就不能再走,这是个误区,玩过推
箱子的应该有体会,注意人的广搜标记数组是二维,且随时更新。
代码示例:
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<queue> using namespace std; typedef struct {     int nbx,nby;     int npx,npy;     int step;     int mark[10][10]; }node; typedef struct {     int x,y; }nodf; node firb,nexb; int map[10][10],m,n; int px,py,bx,by,gx,gy; int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; bool judge(int x,int y) {     if(x<1||x>m||y<1||y>n)     return true;     return false; } bool bfs_people(node point,int pgx,int pgy) {        nodf firp,nexp;     queue<nodf>Q;     int visit[10][10],x,y;     for(int i=1;i<=m;i++)     for(int j=1;j<=n;j++)     visit[i][j]=point.mark[i][j];     firp.x=point.npx,firp.y=point.npy;     Q.push(firp);     while(!Q.empty())     {            firp=Q.front();         Q.pop();         if(firp.x==pgx&&firp.y==pgy)         return false;         for(int i=0;i<4;i++)         {             x=firp.x+dir[i][0],y=firp.y+dir[i][1];             if(judge(x,y)||visit[x][y]==1||visit[x][y]==2||visit[x][y]==-1)             continue;             visit[x][y]=-1;             nexp.x=x,nexp.y=y;             Q.push(nexp);         }     }     return true; }           int bfs_box() {     int visit[10][10][4];     memset(visit,0,sizeof(visit));     int fx,fy,nx,ny;     for(int i=1;i<=m;i++)     for(int j=1;j<=n;j++)     firb.mark[i][j]=map[i][j];     firb.nbx=bx,firb.nby=by;     firb.npx=px,firb.npy=py;     firb.step=0;     queue<node>Q;     Q.push(firb);     while(!Q.empty())     {         firb=Q.front();         Q.pop();         if(firb.nbx==gx&&firb.nby==gy)         return firb.step;         for(int i=0;i<4;i++)         {             fx=firb.nbx,fy=firb.nby;             nx=fx+dir[i][0],ny=fy+dir[i][1];             int x=fx-dir[i][0],y=fx-dir[i][1];             if(judge(nx,ny)||visit[nx][ny][i]==-1||firb.mark[nx][ny]==1)             continue;             if(bfs_people(firb,fx-dir[i][0],fy-dir[i][1]))             continue;             visit[nx][ny][i]=-1;             nexb=firb;             nexb.nbx=nx,nexb.nby=ny;             nexb.step=firb.step+1;             nexb.npx=fx,nexb.npy=fy;             nexb.mark[fx][fy]=0,nexb.mark[nx][ny]=2;             Q.push(nexb);         }     }     return -1; }            int main() {     int T;     scanf("%d",&T);     while(T--)     {         scanf("%d%d",&m,&n);         for(int i=1;i<=m;i++)         for(int j=1;j<=n;j++)         {            scanf("%d",&map[i][j]);            if(map[i][j]==2)            bx=i,by=j;            if(map[i][j]==3)            gx=i,gy=j;            if(map[i][j]==4)            px=i,py=j;         }         printf("%d\n",bfs_box());     }     return 0; }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值