推箱子 两个bfs():一个用来记录人是否能到达指定的位置,另一个用来判断箱子最终是否能够到达指定点,很经典...

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
***************************************************************************************************************************
两个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\n",next.step);
 91                 return ;
 92             }
 93             Q.push(next);
 94         }
 95     }
 96     printf("-1\n");
 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 }
View Code

转载于:https://www.cnblogs.com/sdau--codeants/p/3423136.html

猜你喜欢

转载自blog.csdn.net/weixin_33676492/article/details/94300158