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
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
***************************************************************************************************************************
两个bfs()
***************************************************************************************************************************
1 #include<cstdio> 2 #include<iostream> 3 #include<string> 4 #include<cstring> 5 #include<queue> 6 7 using namespace std; 8 int map[20][20]; 9 int vis1[20][20][4]; 10 int dir[4][2]={1,0,0,1,-1,0,0,-1}; 11 int n,m; 12 int ex,ey,sx,sy,rx,ry; 13 struct node 14 { 15 int x,y; 16 int rx,ry; 17 int step; 18 }; 19 queue<node> Q; 20 int check_bfs(int sx,int sy,int ex,int ey,int xx,int yy) 21 { 22 queue<node> Q1; 23 int vis2[10][10]; 24 memset(vis2,0,sizeof(vis2)); 25 vis2[sx][sy]=1; 26 node pre,next; 27 pre.x=sx,pre.y=sy,pre.step=0; 28 Q1.push(pre); 29 int i; 30 while(!Q1.empty()) 31 { 32 pre=Q1.front(); 33 Q1.pop(); 34 if(pre.x==ex&&pre.y==ey) 35 return 1; 36 for(i=0;i<4;i++) 37 { 38 next=pre; 39 next.x+=dir[i][0]; 40 next.y+=dir[i][1]; 41 if(next.x==ex&&next.y==ey) 42 return 1; 43 if(vis2[next.x][next.y]) 44 continue; 45 if(next.x<0||next.x>=n||next.y<0||next.y>=m) 46 continue; 47 if(map[next.x][next.y]==1||(next.x==xx&&next.y==yy)) 48 continue; 49 vis2[next.x][next.y]=1; 50 Q1.push(next); 51 } 52 } 53 return 0; 54 } 55 void bfs() 56 { 57 int i; 58 node pre,next; 59 memset(vis1,0,sizeof(vis1)); 60 while(!Q.empty()) 61 { 62 pre=Q.front(); 63 Q.pop(); 64 for(i=0;i<4;i++) 65 { 66 next=pre; 67 next.x+=dir[i][0]; 68 next.y+=dir[i][1]; 69 if(vis1[next.x][next.y][i]) 70 continue; 71 if(next.x<0||next.x>=n||next.y<0||next.y>=m) 72 continue; 73 if(map[next.x][next.y]==1) 74 continue; 75 //至此箱子是能走了,但是人能不能推还是问题 76 int xx=pre.x-dir[i][0],yy=pre.y-dir[i][1]; 77 if(xx<0||xx>=n||yy<0||yy>=m) 78 continue; 79 if(map[xx][yy]==1) 80 continue; 81 if(next.rx!=xx||next.ry!=yy) 82 if(!check_bfs(next.rx,next.ry,xx,yy,pre.x,pre.y))//判断人是否能够到达目前的位置 83 continue; 84 //开始更新数据 85 vis1[next.x][next.y][i]=1; 86 next.step++; 87 next.rx=pre.x,next.ry=pre.y; 88 if(next.x==ex&&next.y==ey) 89 { 90 printf("%d ",next.step); 91 return ; 92 } 93 Q.push(next); 94 } 95 } 96 printf("-1 "); 97 } 98 99 int main() 100 { 101 int cas,i,j; 102 node t; 103 scanf("%d",&cas); 104 while(cas--) 105 { 106 scanf("%d%d",&n,&m); 107 memset(vis1,0,sizeof(vis1)); 108 for(i=0;i<n;i++) for(j=0;j<m;j++) 109 { 110 scanf("%d",&map[i][j]); 111 if(map[i][j]==3) ex=i,ey=j; 112 if(map[i][j]==2) sx=i,sy=j; 113 if(map[i][j]==4) rx=i,ry=j; 114 } 115 while(!Q.empty()) Q.pop(); 116 for(i=0;i<4;i++) 117 { 118 int xx=sx+dir[i][0],yy=sy+dir[i][1]; 119 if(xx<0||xx>=n||yy<0||yy>=m) 120 continue; 121 if(map[xx][yy]==1) 122 continue; 123 if(rx==xx&&ry==yy||check_bfs(rx,ry,xx,yy,sx,sy)) 124 { 125 t.x=sx; 126 t.y=sy; 127 t.rx=xx; 128 t.ry=yy; 129 t.step=0; 130 Q.push(t); 131 } 132 } 133 bfs(); 134 } 135 return 0; 136 }