推箱子
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1975 Accepted Submission(s): 501
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
推箱子这个游戏大家都玩过吧!这题是推一个箱子的问题,问人能否把箱子推到指定的位置?
推箱子要能推的三点:
1.箱子前方没有障碍物;
2.箱子后方没有障碍物;
3.人能到达箱子后面。
还有一点要注意,箱子曾经走过的地方再走时可以的,因为有些时候推箱子要先把箱子往后推,人才能移动到箱子后面,让箱子向前推,所以这个标记就要有方向了,之前这里没注意,一直WA,后来才发现。
这题bfs里面有dfs,挺好玩,AC了很爽!
我的代码(详细的注释):
#include <iostream>
#include <stdio.h>
#include <memory.h>
#include <queue>
using namespace std;
int xx[8] = {-1, 0, 1, 0, -1, 0, 1, 0};
int yy[8] = {0, -1, 0, 1, 0, -1, 0, 1};
bool map[10][10][5]; //map[][][]三维数组,记录箱子(x,y)坐标和方向
int a[10][10], b[10][10], c[10][10];
int x1, y1, x2, y2, tx, ty, px, py, ax, ay;
int N, M;
bool flag;
struct node
{
int x, y, px, py, step; //分别保存箱子的坐标(x,y)、人的坐标(px,py)、步数
}n, m;
bool dfs(int x, int y) //深搜:判断人是否能够到达箱子的后面
{
if(x == tx && y == ty) return true; //到达箱子后面
if(x<0 || x>=N || y<0 || y>=M) return false; //越界的返回false
if(x == ax && y == ay) return false; //该点是箱子挡住路了
if(b[x][y] == 1) return false; //该点是墙壁挡住路了
b[x][y] = 1; //走过的标记不能再走
return (dfs(x+1,y) || dfs(x-1,y) || dfs(x,y+1) || dfs(x,y-1)); //往内深搜
}
void set_bc() //初始化深搜时用到的数组b[][]
{
int i, j;
for(i = 0; i < N; i++)
for(j = 0; j < M; j++)
b[i][j] = c[i][j];
}
int main()
{
int i, j, k, t;
scanf("%d", &t);
while(t--)
{
scanf("%d %d", &N, &M);
for(i = 0; i < N; i++)
{
for(j = 0; j < M; j++)
{
cin>>a[i][j];
c[i][j] = b[i][j] = a[i][j];
if(a[i][j] == 2)
x1 = i, y1 = j; //箱子的坐标
if(a[i][j] == 3)
x2 = i, y2 = j; //目标的坐标
if(a[i][j] == 4)
px = i, py = j; //人的坐标
for(k = 0; k < 4; k++)
map[i][j][k] = false; //初始化map[][][]
}
}
flag = false;
n.x = x1; n.y = y1; n.step = 0; //更新第一个push进去的点
n.px = px; n.py = py;
queue<node> Q;
Q.push(n);
while(!Q.empty())
{
m = Q.front();
Q.pop();
if(m.x == x2 && m.y == y2) //箱子到达目标
{
flag = true;
break;
}
for(i = 0; i < 4; i++)
{
n.x = m.x + xx[i]; //后来箱子的位置
n.y = m.y + yy[i];
//i+2 刚好是箱子的反方向位置
tx = m.x + xx[i+2]; //后来人的位置
ty = m.y + yy[i+2];
ax = m.x; //原来箱子的位置
ay = m.y;
n.px = m.px; //原来人的位置
n.py = m.py;
n.step = m.step + 1;
if(n.x>=0 && n.x<N && n.y>=0 && n.y<M && !map[n.x][n.y][i] && a[n.x][n.y]!=1) //箱子前方没问题
{
set_bc(); //初始化b[][]数组
if(tx>=0 && tx<N && ty>=0 && ty<M && a[tx][ty]!=1 && dfs(n.px, n.py)) //人能到达箱子的后方
{
//则箱子能推倒该点(n.px,n.py)
n.px = tx; n.py = ty;
map[n.x][n.y][i] = true; //标记该点和来的这个i方向
Q.push(n);
}
}
}
}
if(flag) printf("%d\n", m.step);
else printf("-1\n");
}
return 0;
}
分享到:
相关推荐
ACM HDU 题目分类是指对 HDU 在线判题系统中题目的分类,总结了大约十来个分类。这些分类将有助于编程选手更好地理解和解决问题。 DP 问题 DP(Dynamic Programming,动态规划)是一种非常重要的算法思想,在 ACM ...
【标题】"HDU题目java实现"所涉及的知识点主要集中在使用Java编程语言解决杭州电子科技大学(HDU)在线评测系统中的算法问题。HDU是一个知名的在线编程竞赛平台,它提供了大量的算法题目供参赛者练习和提交解决方案...
在HDU平台上,每个题目都有一个特定的编号,如HDU1234,这通常是文件或目录的命名方式。因此,“朝花夕拾——hdu”可能是一个包含多个子目录或文件的结构,每个对应一个不同的HDU题目。例如,你可能会看到类似于...
【标题】"HDU_2010.rar"是一个压缩包文件,其中包含了与"HDU 2010"相关的资源,特别是针对"HDU ACM20"比赛的编程题目。"hdu 2010"和"hdu 20"可能是该比赛的不同简称或分类,而"hdu acm20"可能指的是该赛事的第20届...
杭州电子科技大学oj平台上的第1010题,是关于搜索的题目,很不错的题
HDU ACM教案是针对ACM/ICPC(国际大学生程序设计竞赛)的训练教程,旨在帮助参赛者提升算法和编程技能。"搜索入门"这部分内容是教程中的一个重要章节,主要介绍在解决算法问题时如何有效地运用搜索策略。在这个章节...
【搜索入门】是计算机科学领域中的一个重要概念,尤其在算法设计和编程竞赛(如ACM/ICPC)中,搜索技术扮演着至关重要的角色。在这个主题下,我们主要探讨的是如何在复杂问题空间中寻找解决方案的过程。搜索算法是...
4. **循环结束条件**:当遍历完两个字符串的所有位后,还需检查是否还有进位,如果有,则继续将进位值添加到结果数组中。 5. **转换为字符串**:将结果数组中的数字转换为字符形式,并存储到最终的字符串数组中。 #...
【标题】"HDU DP动态规划"涉及到的是在算法领域中的动态规划(Dynamic Programming,简称DP)技术,这是解决复杂问题的一种高效方法,尤其适用于有重叠子问题和最优子结构的问题。动态规划通常用于优化多阶段决策...
《ACM HDU代码大全3000例:探索算法与编程艺术》 在计算机科学领域,特别是竞赛编程中,ACM(国际大学生程序设计竞赛)是一项极富挑战性的活动,它不仅锻炼了参赛者的逻辑思维能力,还提高了他们在算法设计和实现上...
【ACM HDU】指的是在ACM(国际大学生程序设计竞赛,International Collegiate Programming Contest)中,参赛者在杭州电子科技大学(Hangzhou Dianzi University,简称HDU)的在线评测系统上完成并已解决的题目集合...
【标题】:杭电ACMhdu1163 【描述】:这是一道源自杭州电子科技大学(Hangzhou Dianzi University,简称HDU)的ACM编程竞赛题目,编号为1163。这类问题通常需要参赛者利用计算机编程解决数学、逻辑或算法上的挑战,...
【标题】"hdu.rar_HDU 1089.cpp_OJ题求和_hdu_horsekw5_杭电obj" 提供的信息是关于一个压缩文件,其中包含了一个名为 "HDU 1089.cpp" 的源代码文件,这个文件是为了解决杭州电子科技大学(Hangzhou Dianzi ...
HDU是杭州电子科技大学(Hangzhou Dianzi University)举办的一个在线编程竞赛平台,全称为HDU Online Judge。ACM是国际大学生程序设计竞赛(International Collegiate Programming Contest)的缩写,是一个全球性的...
HDU(Hangzhou Dianzi University)是国内外知名的在线编程竞赛平台,主要服务于ACM/ICPC(国际大学生程序设计竞赛)以及相关的算法训练。"HDU最全ac代码"这个压缩包很可能是包含了在HDU平台上解题通过的完整源代码...
HDU ACM代码集合是针对ACM(国际大学生程序设计竞赛,International Collegiate Programming Contest)的一份资源,这个压缩包中的代码涵盖了多种算法,是参赛者或对算法学习感兴趣的人宝贵的参考资料。ACM竞赛旨在...
总的来说,"acm课件搜索(杭电)(HDU)"这一主题为ACM学习者提供了一个宝贵的资料库,特别是对搜索算法的探讨,有助于参赛者提升在竞赛中的表现。通过深入学习和实践,学生能够熟练掌握DFS和BFS,以及其他相关算法...
HDU_ACM培训课件是面向参与ACM(国际大学生程序设计竞赛,International Collegiate Programming Contest,简称ICPC)的学员准备的一套完整的教程资源。这个压缩包包含了丰富的学习资料,旨在帮助参赛者提升编程技能...
HDU1059的代码
hdu1001解题报告