推箱子
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6089 Accepted Submission(s): 1743
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
Author
Ignatius.L & weigang Lee
/* 看到题目,要求的问题就是箱子最少要移动多少步。、 地图的状态在变化的就是1.人的位置,2.箱子的位置 (初略估计49*49)是不会爆的 终止条件是箱子到达目标位置。 这题是以箱子为主的,我们要考虑的就是箱子移动的方向 (它有四个方向,即上下左右),能移动的条件就是( 1,人可以到达箱子的另一旁(7*7时间复杂度)。2,移动的地方不是墙) */ #include <iostream> #include <stdio.h> #include <cstring> #include <algorithm> #include <queue> #include <map> using namespace std; const int MAXN = 10; int n, m;//n为行m为列 int ex, ey;//目标地址 int ditu[MAXN][MAXN];//1是墙 //pay[x1][y1][x2][y2]表示的就是箱子在(x1,y1),人在(x2,y2)所花费的最小步数 int pay[MAXN][MAXN][MAXN][MAXN]; struct node { int x1, y1, x2, y2; int pay; }; int fx[] = {1,0,-1,0,1}; void init() { for(int i=0; i<MAXN; i++) { for(int j=0; j<MAXN; j++) { ditu[i][j] = 1; } } memset(pay,-1,sizeof pay); } struct node1 { int x, y; }; bool vis[MAXN][MAXN]; bool check(node s, node e) { //如果箱子另一边是墙,就不能推 if(ditu[e.x2][e.y2] == 1)return false; node1 a, b; a.x = s.x2; a.y = s.y2; memset(vis,0,sizeof vis); vis[a.x][a.y] = true; queue<node1>Q; Q.push(a); while(!Q.empty()) { a = Q.front(); Q.pop(); if(a.x == e.x2 && a.y == e.y2)return true; for(int i=0; i<4; i++) { b.x = a.x + fx[i]; b.y = a.y + fx[i+1]; //墙不可走 if(ditu[b.x][b.y]==1)continue; //箱子不可走 if(b.x==s.x1&&b.y==s.y1)continue; //没有走过,才走 if(!vis[b.x][b.y]) { vis[b.x][b.y] = true; Q.push(b); } } } return false; } int bfs(node s) { node a, b; a = s; a.pay = 0; pay[a.x1][a.y1][a.x2][a.y2] = a.pay; queue<node>Q; Q.push(a); while(!Q.empty()) { a = Q.front(); Q.pop(); if(a.x1==ex&&a.y1==ey)return a.pay; for(int i=0; i<4; i++) { b.x1 = a.x1 + fx[i]; b.y1 = a.y1 + fx[i+1]; //如果目标是墙,不能走 if(ditu[b.x1][b.y1] == 1)continue; //想要推动箱子必须到达另一面 b.x2 = a.x1 - fx[i]; b.y2 = a.y1 - fx[i+1]; if(check(a,b)) { b.pay = a.pay + 1; if(pay[b.x1][b.y1][b.x2][b.y2] == -1 || pay[b.x1][b.y1][b.x2][b.y2] > b.pay) { pay[b.x1][b.y1][b.x2][b.y2] = b.pay; Q.push(b); } } } } return -1; } int main() { int t, i, j; node s; scanf("%d",&t); while(t--) { init(); scanf("%d%d",&n, &m); for(i=1; i<=n; i++) { for(j=1; j<=m; j++) { scanf("%d",&ditu[i][j]); if(ditu[i][j]==2) { s.x1 = i; s.y1 = j; ditu[i][j] = 0; }else if(ditu[i][j]==3) { ex = i; ey = j; ditu[i][j] = 0; }else if(ditu[i][j]==4) { s.x2 = i; s.y2 = j; ditu[i][j] = 0; } } } printf("%d\n", bfs(s)); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-22 13:13:13