HDU 1254 推箱子 搜索中搜索

来源:互联网 发布:不喝牛奶 知乎 编辑:程序博客网 时间:2024/05/16 14:26
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
15 50 3 0 0 01 0 1 4 00 0 1 0 01 0 2 0 00 0 0 0 0
 

Sample Output
4

题解:题目要求计算箱子所需的最小步数,而不是人的。①:每次移动箱子时,就要考虑人能否到达箱子的后面,这样,箱子才能被往前推。②:在判断人是否能到达箱子的后面时要注意此时人不能走到箱子的位置,也就是每次移动箱子时,就要把现在箱子的位置标记为人不能通过,待判断完后,再取消刚才对箱子的标记。③:接着是考虑箱子能否往回走,实际上对于每一点时,箱子可重复走到,但从每个方向走到一个点时只能走一次。所以需要一个数组来进行判断箱子是不是已经从这个方向走过这个点了。0 0 0 1 0 00 0 0 1 0 3 0 0 0 2 4 00 0 0 1 0 0 0 0 0 1 0 0 

此时就需要重复走到一点 但是方向不同

#include "stdio.h"#include "queue"#include "string.h"using namespace std;int vis[15][15][4];int kk,n,m;int map[10][10];struct pnode  {int x, y;};struct node{int x,y,step;pnode person;} ; pnode startP,startB,targetB;int dir[4][2] = { -1,0, 1,0, 0,-1, 0,1 };//上下左右 int bfs_person(pnode a,pnode b) // 平常的搜索 {int i;queue<pnode >q;int mark[15][15];memset(mark,0,sizeof(mark));pnode now,next;mark[a.x][a.y]=1;q.push(a);while (!q.empty()){now=q.front();q.pop();if(now.x==b.x&&now.y==b.y){return 1;}for(i=0;i<4;i++){next.x = now.x + dir[i][0];            next.y = now.y + dir[i][1];if(next.x>=0&&next.x<n&&next.y>=0&&next.y<m){if((map[next.x][next.y]!=1)&&!mark[next.x][next.y]){mark[next.x][next.y]=1;q.push(next);}}}}return 0;}int bfs_box(){int i;memset(vis,0,sizeof(vis));queue<node>q;node now,next;now.x=startB.x;now.y=startB.y;now.step=0;now.person.x=startP.x;now.person.y=startP.y;q.push(now);pnode pF ;// 人要到箱子的前面; while (!q.empty()){now=q.front();q.pop();if( now.x==targetB.x && now.y==targetB.y )            return now.step;for(i=0;i<4;i++){next.x = now.x + dir[i][0];            next.y = now.y + dir[i][1];            pF.x = now.x - dir[i][0]; //            pF.y = now.y - dir[i][1]; // 推箱子的人需要到的地方if(next.x>=0&&next.x<n&&next.y>=0&&next.y<m){if(map[next.x][next.y]!=1){if(vis[next.x][next.y][i]==0){int temp;temp=map[now.x][now.y];map[now.x][now.y]=1;// 箱子位置人不能走if(bfs_person(now.person,pF)){next.step=now.step+1;next.person.x=now.x;//next.person.y=now.y;//人代替箱子的位置 vis[next.x][next.y][i]=1;q.push(next);}map[now.x][now.y]=temp; }}}} }return -1;}int main(){int i,j;scanf("%d",&kk);while (kk--){scanf("%d%d",&n,&m);for(i=0;i<n;i++){for(j=0;j<m;j++){scanf("%d",&map[i][j]);if(map[i][j]==2){startB.x=i;startB.y=j;}if(map[i][j]==3){targetB.x=i;targetB.y=j;}if(map[i][j]==4){startP.x=i;startP.y=j;}}}printf("%d\n",bfs_box());}} 


0 0
原创粉丝点击