推箱子
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; }