华为机试题43-迷宫问题

2023-11-07

描述

定义一个二维数组 N*M ,如 5 × 5 数组下所示:


int maze[5][5] = {
0, 1, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
};


它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的路线。入口点为[0,0],既第一格是可以走的路。

数据范围: 2≤n,m≤10  , 输入的内容只包含 0≤val≤1 

输入描述:

输入两个整数,分别表示二维数组的行数,列数。再输入相应的数组,其中的1表示墙壁,0表示可以走的路。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。

输出描述:

左上角到右下角的最短路径,格式如样例所示。

示例1

输入:

5 5
0 1 0 0 0
0 1 1 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0

输出:

(0,0)
(1,0)
(2,0)
(2,1)
(2,2)
(2,3)
(2,4)
(3,4)
(4,4)

示例2

输入:

5 5
0 1 0 0 0
0 1 0 1 0
0 0 0 0 1
0 1 1 1 0
0 0 0 0 0

输出:

(0,0)
(1,0)
(2,0)
(3,0)
(4,0)
(4,1)
(4,2)
(4,3)
(4,4)

说明:

注意:不能斜着走!!


解题思路:

这道题我们使用深度优先搜索(DFS)来解题。

假设我们在迷宫内的某一点(i,j),且该点周围不存在障碍,也不靠墙,我们下一步可以去到的位置是:向右,(i,j+1);向下,(i+1,j);向左,(i,j-1);向上,(i-1,j)。

可以想象一下,假设我们在迷宫内的某一点,我们采取的方法就是试探,由于只能横着走或竖着走,所以我们只能往上下左右走,这里我们给这4个方向定一个优先级,比如所在之处,可以往多个方向走,我们先往哪个方向走?定的方向优先级为:右,下,左,上。就是说,如果先试探的方向右是障碍或者墙壁,那肯定不能走,那么往下试探,发现往下遇到障碍,那也不能走,直到遇到一个方向可以通行;因为题目要求最短路径,那么走过的位置就不能再走了,不然可以在某个位置反复横跳,最后再去终点,这也算一种路径,显然这也没有意义。

举个例子:

0 1 0 0 0

0 1 0 1 0

0 0 0 0 1

0 1 1 1 0

0 0 0 0 0

按照我们上述提到右下左上原则,迷宫里的人会按照红色字体先走:

0 1 0 0 0

1 0 1 0

2 3 4 5 1

0 1 1 1 0

0 0 0 0 0

这时候会发现走到死胡同里了,5的右边下边上边都是障碍,左边是已经走过的路,这个时候该怎么走?

我们在迷宫里迷路了也只能往回走,再试试其他的路能否走通到达目的地,这叫回溯。

于是我们往回撤一步,并将5这个位置标记为没走过,从4这个位置再重新开始试探,由于往右到5已经试过了,不能走通,往下是障碍,左边3已经走过了,那就只能往上走,肉眼可见那是一条死胡同,到最后肯定会回到4这个位置,这时候右下左上都试探过了,没有能走通,那就再往会撤一步,并将4这个位置标记为没走过,从3这个位置再重新开始试探,发现3没有方向可以走通,回溯到2,从2开始,继续试探,就会有以下路径:

0 1 0 0 0

1 1 0 1 0

2 0 0 0 1

3 1 1 1 0

4 5 6 7 8

按照这个思路,我们可以写代码了,我们用两个数组表示横向和纵向上的增量;

x_incre[4]={0,1,0,-1}, (横向)

y_incre[4]={1,0,-1,0}; (纵向)

第0次试探的方向是(i+0,y+1),即往右

第1次试探的方向是(i+1,y),即往下

……

用一个for循环来遍历试探每一个方向,可以减少重复代码。

用一个二维数组sign来标记某一点是否已经走过,初始化为0,走过后置为1,避免反复横跳。

由于要输出最短路径的各个坐标,我们可以用一个n行2列的二维数组记录每到一个点的坐标

下面为代码实现:

#include <stdio.h>
#define    N    10
int sign[N][N],pos[1000][2],n,m,cnt,maze[N][N],flag;
void dfs(int x,int y)
{
    pos[cnt][0]=x;pos[cnt][1]=y;cnt++;    //pos二维数组记录到达位置的下标
    sign[x][y]=1;                        //sign二维数组在相同位置值1,表示这个位置已经走过
    if(x==n-1&&y==m-1)                   
    {
        flag=1;                        
        return;                         //到达终点,flag置1,并返回上一级dfs递归调用
    }
    int i,j,k;
    int x_incre[4]={0,1,0,-1},y_incre[4]={1,0,-1,0};
    for(k=0;k<4;k++)
    {
        i=x+x_incre[k];j=y+y_incre[k];        //i,j为下次试探的位置
        if(i>=0&&j>=0&&i<n&&j<m&&!maze[i][j]&&!sign[i][j])
        {                            //不能超出迷宫,也不能走障碍和已经走过的点
            dfs(i,j);                //进入下一步位置的试探
            if(flag)                
                return;         //试探的路径可以达到终点,返回上一级dfs调用
        }
    }
    sign[i][j]=0;   //如果没有试探出终点而返回,也没能在4次方向试探中找到可走的路
    cnt--;      //那么说明这个点走错了,标记这个点没走过,并将坐标弹出,结束这层dfs,返回上一层
}
int main()
{
    int i,j,startx=0,starty=0;    
    scanf("%d%d",&n,&m);
    for(i=0;i<n;i++)
        for(j=0;j<m;j++)
            scanf("%d",&maze[i][j]);
    dfs(startx,starty);    //起始位置为(0,0)
    for(i=0;i<cnt;i++)
        printf("(%d,%d)\n",pos[i][0],pos[i][1]);
    return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

华为机试题43-迷宫问题 的相关文章

  • Android作业中遇到的各种问题

    1 如何设置Edit View不可输入不可编辑不可点击 eidtex为要设置的文本框的id eidtext setEnabled false 去掉点击时编辑框下面横线 eidtext setFocusable false 不可编辑 eidt
  • antd vue时间选择器(年选择器)

    antd vue时间选择器 年选择器 最近项目中用到了antd vue 项目中的版本是1 5 2版本 在做日期选择器时发现只有日 周 月份选择器 独独缺少年份选择器 如果你的项目也是怕升级对整体影响太多 不妨试试下面这种方式来达到年份选择效
  • 用递归求和:1+2+3+4+....n.

    1 具体代码实现 public class Example2 public static void main String args int n 100 int value add n System out println value pu
  • Windows下 VS2015编译RocksDB

    VS2015编译RocksDB RocksDB 是一个来自 facebook 的可嵌入式的支持持久化的 key value 存储系统 也可作为 C S 模式下的存储数据库 但主要目的还是嵌入式 RocksDB 基于 LevelDB 构建 1

随机推荐

  • python在定位元素中加入参数化

    我们在web自动化时 需要用到上个定位的值 来定位下个定位的方法 这个时候就需要用参数传递了 解决如下 我们如果要想获取这个页面的全部名字需要用 driver find elements的定位 不要用driver find element
  • 单片机新手指导2:STM32单片机学习步骤---偏编程方向

    学习步骤 编程方向 写在前面 本文为笔者从单片机小白到略懂到能完成单片机大项目过程中的身心体会 做下总结供后来者参考 第零步 1 准备好一个爱学习 痴迷技术 不怕秃头 不怕熬夜 追求上进的自己 2 调研并选一套适合自己的STM32学习板 不
  • 关于windows安装wsl,出现WslRegisterDistribution failed with error: 0x8007019e The Windows Subsystem错误的解决方案

    前倾概要 在Microsoft store安装ubuntu 18 04成功启动后 出现了该错误并提示按任意键退出 如下图所示 由于我忘了截图 所以只能去别的博主那盗图 解决方案 首先需要安装windows的子系统支持 步骤 1 win x
  • Qlistwidget获取当前选项的文本的方法

    PYQT5 Qlistwidget获取当前选项文本的方法 创建一个Qlistwidget 获取当前的选择的item currentItem self listWidget types currentItem print currentIte
  • 提升学生群体中的STEAM教育核心素养

    STEAM教育源自STEM教育 是当今国际探索21世纪人才培养的一种教育理念与举措 美国首倡STEM教育并将其作为提升国家竞争力的战略之一 旨在加强科学 Science 技术 Technology 工程 Engineering 与数学 Ma
  • 基于MVC架构的项目中的数据库数据表结构的更新

    1 在整个项目中对于数据库的操作及其处理 是通过在model类中添加数据模型i类之后去在controllers中执行增加新的构架和迁移文件的方式 最后通过这个迁移来更新数据库 采用第一种方法的现在知道的好处就是因为表的定义是在程序中弄得再通
  • winserver2008 服务器添加新用户及设置远程桌面管理

    winserver2008 服务器添加新用户及设置远程桌面管理 1 点击 开始 管理工具 计算机管理 本地用户和组 2 右击 用户 执行 新用户 命令 如图 输人用户信息 在 新用户 对话框中 输人相应信息 3 单击 创建 按钮完成创建 而
  • 100个 ChatGPT 提示(Prompt)优化高质量提问案例

    众所周知 如何使用好 ChatGPT 关键在于如何提问 如何提出高质量的问题 这就涉及到如何组织提示 Prompt OpenAI 官方称之为提示工程 Prompt Engineering 我们可以通过在提问环节对提示进行优化来得到最准确和相
  • 删除本地缓存localStorage的某个字段

    移除localStorage 某个对应的字段 localStorage removeItem maxPostion this itemInfo itemid 删除localStorage 里的数组 function f i var list
  • 文明重启如何修改服务器,文明重启如何开启社区服 创建社区服方法

    现在在文明重启中 我们除了可以玩普通的模式之外 还可以自己当服主 创建社区服 邀请其他的玩家跟自己一起玩 那么文明重启如何开启社区服呢 感兴趣的小伙伴跟着小编一起来看看创建的方法吧 文明重启如何开启社区服 社区服的开启方法其实很简单 但是首
  • 焊接技巧视频(热风枪/QFP/QFN/SOP/穿孔/烙铁头/助焊膏/连锡/飞线/回流焊)

    https www bilibili com video BV1wJ411B73v p 1 vd source cc0e43b449de7e8663ca1f89dd5fea7d
  • 【ModelArts系列】华为ModelArts Notebook训练yolov3模型(开发环境)

    一 参考资料 二 相关介绍 在ModelArts的 notebook中运行ModelZoo中模型 以yolov3为例 训练集为 COCO2014 运行环境 ModelArts notebook 模型 ModelZoo yolov3 数据集
  • elementUI + vue实现 Excel筛选功能

    element仿照EXCEL 和后端交互数据联动筛选 公司要el table基础上实现一个excel的功能 element的不能满足我的需求于是自己写了一个 tableTool vue组件实现 组件介绍 组件为筛选框 配合element中e
  • AndroidManifest.xml 最全详解

    AndroidManifest xml 是每个android程序中必须的文件 它位于整个项目的根目录 我们每天都在使用这个文件 往里面配置程序运行所必要的组件 权限 以及一些相关信息 但是对于这个文件 我们真正又了解多少了 还是只是停留在只
  • leetcode 142题 环形链表找入环点 python js解法

    题目 给定一个链表的头节点 head 返回链表开始入环的第一个节点 如果链表无环 则返回 null 如果链表中有某个节点 可以通过连续跟踪 next 指针再次到达 则链表中存在环 为了表示给定链表中的环 评测系统内部使用整数 pos 来表示
  • gets(str)函数和scanf(“%s“,str)区别

    gets str 函数和scanf s str 区别 转自 https zhidao baidu com question 290403568 html 二者都是从终端读入字符串 功能为 1 gets功能为读入一行 并将换行符转换为字符串结
  • Linux高级应用(三)液晶屏显示图片

    一 C语言调用外部函数 1 使用extern关键字来声明 lcd c include
  • 大型文件传输慢、传输中断怎么办?

    由于业务需要 如今 发送100M以上甚至是GB级大小的文件变得越来越普遍 比如设计稿件 软件开发包 视频素材等 一张图片2 3G 一本书稿4 5G 一个视频片段3 4G 一份设计图纸十几G 甚至还有上百G的大文件 企业如何高效的管理和传输大
  • 列主元lu分解法_直接法

    主要研究的数学问题 研究怎么求解线性方程组 的问题 以下推导 都是假设矩阵 非奇异 高斯消去法 是求解线性方程组 的方法 什么是高斯消去法 先把系数矩 阵化为上三角 然后 对线性方程组进行 回代求解 2 算法评价 主要通过计算加减乘除的次数
  • 华为机试题43-迷宫问题

    描述 定义一个二维数组 N M 如 5 5 数组下所示 int maze 5 5 0 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0 它表示一个迷宫 其中的1表示墙壁 0表示可以走的路 只能横