迷宫问题(牛客)

2023-05-16

题目描述:

定义一个二维数组N*M(其中2<=N<=10;2<=M<=10),如5 × 5数组下所示: 
int maze[5][5] = {
        0, 1, 0, 0, 0,
        0, 1, 0, 1, 0,
        0, 0, 0, 0, 0,
        0, 1, 1, 1, 0,
        0, 0, 0, 1, 0,
};
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。入口点为[0,0],既第一空格是可以走的路。
Input
一个N × M的二维数组,表示一个迷宫。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。

注意:这里的唯一解指的是最短路径只有一条,但是有多种可以走出迷宫的路径

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

5 5
0 1 0 0 0
0 1 0 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)

做题思路:

首先,必然是递归的思想,去试探出一条可以走通的路径。但必须考虑两个问题:回溯和最短路径

递归思路:

  • 对于点(x,y),首先判断是否达到终点,即x==N,y==M是否成立,如果第一次成立,就把走通的路径赋值给最短路径,之后再次走通的路径,将其长度与最短路径进行比较,如果更小,就取而代之
  • 假设(x,y)就在当前可以走通的路径(即current_step)内,把(x,y)加入路径节点中,同时把(x,y)置为1表示这个节点已经走过了
  • 对(x,y)的上下左右方向进行试探若是某个方向的节点可以走通,这个新节点就重复(x,y)的做法,即再次进入递归函数
  • 如果上下左右都走不通,那就把节点(x,y)从当前可以走通的路径中pop掉,同时把(x,y)置为0

    这就是递归函数的四部分,可以发现,在这里面并没有进行return

  • 走不通的情况,比如当前在(1,0),向右可以走通进入(1,1),但是(1,1)的上下左右都走不通,就pop了,同时(1,1)又变回了0,函数结束,也就实现了return。并且我们无需担心(1,0)点会再次向右试探,不停地pop,push陷入死循环,因为进入(1,0)向右试探,进入递归函数,函数结束后,它就自动顺序执行其他方向的试探了。也就是说走不通的路,一定不会被再次试探。由此确保,不return,也可以把所有的路径试探完。
  • 能走通的情况,走通虽然进行了最短路径的更新,但是也没有进行return,我们还要寻找其他的最短路径。
  • 那么已经走通的情况下如果不return会出现什么情况?在进行路径更新后,在终点,还会顺序执行对四个方向的试探(但是到达终点时候一定会是有方向,那个方向刚走过的节点值已经变成1,而向右向下是边界不能走,所以只剩一个方向可能走出去)。如果可以走出去,或许可能有一条路再次回到终点,但这条路是在上一条走通的道路的基础上进行的,肯定更长,最短路径不会被更新,同时就相当于回到了已经走通的情况。如果不能在此基础上走通,自然就不停地pop,就变成了上述走不通的情况了

AC代码:

#include<iostream>
#include<vector>
using namespace std;

struct Coordinate{
	int x;
	int y;
};
int matrix[1000][1000];
vector<Coordinate> current_step;
vector<Coordinate> best_step;

void Find_way(int x,int y);

int N,M; //代表行数和列数 
int main()
{
	while( cin>>N>>M ){
		current_step.clear();
		best_step.clear();
		for(int i=0; i<N; i++){
			for(int j=0; j<M; j++){
				cin>>matrix[i][j];
			}
		}
		
		Find_way(0,0);
		
		for(int i=0; i<best_step.size(); i++){
			cout<<"("<<best_step[i].x<<","<<best_step[i].y<<")"<<endl;
		} 
	}
} 
void Find_way(int x,int y)
{
	Coordinate c = {x,y};
	current_step.push_back(c); //假设当前节点是当前走向终点路线上的一点
	matrix[x][y] = 1;
	
	if( x==N-1&&y==M-1 ){ //当前路线走到了终点 
		if( best_step.empty()||current_step.size()<best_step.size() ){  //如果当前是第一次走通,或者是新找到的路径比之前找到的最短路径还要短,就进行替换 
			best_step = current_step; 
		} 
	} 
	
	if( x-1>=0&&matrix[x-1][y]==0 ){//向上可以走通
		Find_way(x-1,y);
	} 
	if( y-1>=0&&matrix[x][y-1]==0 ){//向左可以走通
		Find_way(x,y-1);
	}
	if( x+1<N&&matrix[x+1][y]==0 ){//向下可以走通
		Find_way(x+1,y);
	}
	if( y+1<M&&matrix[x][y+1]==0 ){//向右可以走通
		Find_way(x,y+1);
	}
	
	current_step.pop_back();
	matrix[x][y]=0; //当前节点走不下去,就返回上一个节点 
}

 

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

迷宫问题(牛客) 的相关文章

  • 国内银行卡BIN号(Bank Identification Number)速查简表

    转载 xff1a https blog csdn net qq 37960324 article details 82981824 国内银行卡BIN号 Bank Identification Number 速查简表 银行名称 银行卡 卡BI
  • 判断一个对象是否为数组的4种方法

    问题描述 在js中判断数据类型通常使用typeof xff0c 但是typeof在判断数组和对象时的结果都是object console span class token punctuation span span class token
  • 去重三种方法

    数组去重三种方法 问题情境 去除数组中重复的元素 输出不重复的元素数组 思路方向 将数组中重复的元素删除将数组中不重复的元素取出利用其它 JavaScript 特性和 API 直接去重 这一思路中有些 API 涉及ES6中的某些知识暂不提及
  • 百度地图API简介

    百度地图API 简介 百度地图API是百度地图开放平台面向广大政府 企业 互联网等开发者开放的免费地图服务 拥有定位 地图 导航 轨迹 路况 路线规划 搜索 xff0c 七大基础地图服务能力 xff0c 并将七大服务能力开放给各行业开发者使
  • svg和canvas的区别简析

    Canvas和SVG是html5中支持2种可视化技术 xff0c 都是可以在画布上绘制图形和放入图片 下面来介绍和分析一下他们 一 Canvas 和 SVG 简介 1 什么是Canvas xff1f Canvas 是H5新出来的标签 Can
  • 微信小程序:实现长按扫描二维码

    小程序内置扫描二维码 image 使用小程序提供的image组件 xff0c image组件上有一个show menu by longpress的属性 xff0c 设置为true lt image show menu by longpres
  • 微信小程序:小程序常见问题及解决方案

    文章目录 原生组件显示在遮罩层上面的问题scroll view高度适配问题表单控件聚焦后页面上推问题小程序web view页面返回到小程序页面 原生组件显示在遮罩层上面的问题 在小程序中使用原生的表单组件时 xff0c 在有弹出框出现的情况
  • Echarts:惊艳的Map

    大家在网上看天气预报的时候应该就看到过在中国地图上显示不同省份的温度 xff0c 并根据温度的高低显示不同的颜色 xff0c 又或者看到各个省份的新冠肺炎新增人数 xff0c 根据不同的新增人数显示不同的颜色之类的图像 这些 xff0c 使
  • 微信小程序性能优化

    文章目录 小程序优化首屏加载优化白屏优化运行时性能渲染性能优化页面切换优化 小程序优化 首屏加载优化 删除无用代码 资源文件 开启按需加载组件 span class token comment app json span span clas
  • webStorage

    cookie 在webStorage出现之前在浏览器端存储数据通常使用cookie cookie是某些网站为了辨别用户身份 xff0c 进行Session跟踪而储存在用户本地终端上的数据 xff08 通常经过加密 xff09 xff0c 由
  • alembic 命令的使用

    初始化 alembic init alembic 查看历史head alembic span class token function history span span class token operator span span cla
  • centos 6 镜像源不再可用

    2020 12 02 centos 停止更新centos 6 xff0c 官网镜像源不可用 http mirror centos org centos 6 6 readme This directory and version of Cen
  • Linux安装配置vnc

    1 检测 vnc有没有安装 rpm qa grep tigervnc 或 rpm qa grep vnc 显示如下信息 xff0c 证明 vnc已经安装 1 1 若未安装 xff0c 安装步骤如下 1 1 1 cd 到 vnc 安装包目录下
  • shell变量的五种赋值方式

    shell变量的赋值https blog 51cto com u 14881361 2673174 一 直接赋值 格式为 xff1a 变量名 61 变量值 x1f416 直接赋值时禁止在 等号 61 两端添加空格 span class to
  • CommonJS和ES6模块化的区别

    ES6 模块与 CommonJS 模块存在以下差异 xff1a 1 语法上 CommonJS 使用的是 module exports 61 导出一个模块对象 xff0c require file path 引入模块对象 xff1b ES6使
  • bug解决: Cause: org.xml.sax.SAXParseException; lineNumber: 2; columnNumber: 6; 不允许有匹配 “[xX][mM][lL]“ 的

    Exception encountered during context initialization span class token operator span cancelling refresh attempt span class
  • 云计算基础

    待到秋来九月八 xff0c 我花开后百花杀 数据中心发展阶段企业自建EDCIDC托管 租用云计算三者对比 云计算核心特征云计算参考模型云计算的关键特点按需服务资源池化弹性扩展泛网络访问服务可度量 云计算服务模式云计算技术架构云计算的4个部署
  • 前端npm或yarn装包踩坑——安装超时失败,设置镜像源不生效

    问题描述 xff1a 使用npm或yarn进行安装依赖包时 xff0c 无响应超时 xff0c 随即设置镜像源指向淘宝镜像 xff0c 但始终不生效 问题原因 xff1a 无响应 网络等原因 xff0c 导致npm或yarn装包失败 xff

随机推荐