`

hdu 1254 推箱子(广搜中有深搜!爽!)

阅读更多

推箱子

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
4
 
        推箱子这个游戏大家都玩过吧!这题是推一个箱子的问题,问人能否把箱子推到指定的位置?
推箱子要能推的三点:
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;
}
 
0
5
分享到:
评论

相关推荐

    ACM HDU题目分类

    ACM HDU 题目分类是指对 HDU 在线判题系统中题目的分类,总结了大约十来个分类。这些分类将有助于编程选手更好地理解和解决问题。 DP 问题 DP(Dynamic Programming,动态规划)是一种非常重要的算法思想,在 ACM ...

    HDU题目java实现

    【标题】"HDU题目java实现"所涉及的知识点主要集中在使用Java编程语言解决杭州电子科技大学(HDU)在线评测系统中的算法问题。HDU是一个知名的在线编程竞赛平台,它提供了大量的算法题目供参赛者练习和提交解决方案...

    hdu.rar_hdu

    在HDU平台上,每个题目都有一个特定的编号,如HDU1234,这通常是文件或目录的命名方式。因此,“朝花夕拾——hdu”可能是一个包含多个子目录或文件的结构,每个对应一个不同的HDU题目。例如,你可能会看到类似于...

    HDU_2010.rar_hdu 2010_hdu 20_hdu acm20

    【标题】"HDU_2010.rar"是一个压缩包文件,其中包含了与"HDU 2010"相关的资源,特别是针对"HDU ACM20"比赛的编程题目。"hdu 2010"和"hdu 20"可能是该比赛的不同简称或分类,而"hdu acm20"可能指的是该赛事的第20届...

    hdu1010搜索算法

    杭州电子科技大学oj平台上的第1010题,是关于搜索的题目,很不错的题

    hdu acm 教案(7)

    HDU ACM教案是针对ACM/ICPC(国际大学生程序设计竞赛)的训练教程,旨在帮助参赛者提升算法和编程技能。"搜索入门"这部分内容是教程中的一个重要章节,主要介绍在解决算法问题时如何有效地运用搜索策略。在这个章节...

    HDUACM201303版_10搜索入门

    【搜索入门】是计算机科学领域中的一个重要概念,尤其在算法设计和编程竞赛(如ACM/ICPC)中,搜索技术扮演着至关重要的角色。在这个主题下,我们主要探讨的是如何在复杂问题空间中寻找解决方案的过程。搜索算法是...

    hdu1250高精度加法

    4. **循环结束条件**:当遍历完两个字符串的所有位后,还需检查是否还有进位,如果有,则继续将进位值添加到结果数组中。 5. **转换为字符串**:将结果数组中的数字转换为字符形式,并存储到最终的字符串数组中。 #...

    HDU DP动态规划

    【标题】"HDU DP动态规划"涉及到的是在算法领域中的动态规划(Dynamic Programming,简称DP)技术,这是解决复杂问题的一种高效方法,尤其适用于有重叠子问题和最优子结构的问题。动态规划通常用于优化多阶段决策...

    ACM hdu 代码大全3000例,部分代码有详细解析

    《ACM HDU代码大全3000例:探索算法与编程艺术》 在计算机科学领域,特别是竞赛编程中,ACM(国际大学生程序设计竞赛)是一项极富挑战性的活动,它不仅锻炼了参赛者的逻辑思维能力,还提高了他们在算法设计和实现上...

    ACM HDU

    【ACM HDU】指的是在ACM(国际大学生程序设计竞赛,International Collegiate Programming Contest)中,参赛者在杭州电子科技大学(Hangzhou Dianzi University,简称HDU)的在线评测系统上完成并已解决的题目集合...

    杭电ACMhdu1163

    【标题】:杭电ACMhdu1163 【描述】:这是一道源自杭州电子科技大学(Hangzhou Dianzi University,简称HDU)的ACM编程竞赛题目,编号为1163。这类问题通常需要参赛者利用计算机编程解决数学、逻辑或算法上的挑战,...

    hdu.rar_HDU 1089.cpp_OJ题求和_hdu_horsekw5_杭电obj

    【标题】"hdu.rar_HDU 1089.cpp_OJ题求和_hdu_horsekw5_杭电obj" 提供的信息是关于一个压缩文件,其中包含了一个名为 "HDU 1089.cpp" 的源代码文件,这个文件是为了解决杭州电子科技大学(Hangzhou Dianzi ...

    Hdu1000—2169部分代码

    HDU是杭州电子科技大学(Hangzhou Dianzi University)举办的一个在线编程竞赛平台,全称为HDU Online Judge。ACM是国际大学生程序设计竞赛(International Collegiate Programming Contest)的缩写,是一个全球性的...

    HDU最全ac代码

    HDU(Hangzhou Dianzi University)是国内外知名的在线编程竞赛平台,主要服务于ACM/ICPC(国际大学生程序设计竞赛)以及相关的算法训练。"HDU最全ac代码"这个压缩包很可能是包含了在HDU平台上解题通过的完整源代码...

    hdu ACM代码 每种算法都有分类

    HDU ACM代码集合是针对ACM(国际大学生程序设计竞赛,International Collegiate Programming Contest)的一份资源,这个压缩包中的代码涵盖了多种算法,是参赛者或对算法学习感兴趣的人宝贵的参考资料。ACM竞赛旨在...

    acm课件搜索(杭电)(HDU)

    总的来说,"acm课件搜索(杭电)(HDU)"这一主题为ACM学习者提供了一个宝贵的资料库,特别是对搜索算法的探讨,有助于参赛者提升在竞赛中的表现。通过深入学习和实践,学生能够熟练掌握DFS和BFS,以及其他相关算法...

    HDU_ACM培训课件(完整版)

    HDU_ACM培训课件是面向参与ACM(国际大学生程序设计竞赛,International Collegiate Programming Contest,简称ICPC)的学员准备的一套完整的教程资源。这个压缩包包含了丰富的学习资料,旨在帮助参赛者提升编程技能...

    HDU1059的代码

    HDU1059的代码

    hdu1001解题报告

    hdu1001解题报告

Global site tag (gtag.js) - Google Analytics