首页 > 编程语言 >迷宫问题(C++): 最短路径计算(队列)&& 路径输出(栈)(附一个易错点~)

迷宫问题(C++): 最短路径计算(队列)&& 路径输出(栈)(附一个易错点~)

时间:2024-04-07 16:29:19浏览次数:45  
标签:bd 易错 cur int 路径 sy re && 起点

迷宫问题大同小异,先直接上代码ba~:

#include<bits/stdc++.h> // 包含标准库头文件
using namespace std; // 使用标准命名空间
#define size 100 // 定义迷宫大小
typedef struct{ // 定义结构体STU
    int x, y;
}STU;
queue<STU>q; // 定义队列q

int n, bd[size][size]={0}, re_bd[size][size]={0}; // 定义迷宫大小n,迷宫数组bd和最短路径数组re_bd
int help[8][2] = {{0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}}; // 定义八个方向的移动

int main()
{
	
	cin>>n; // 输入迷宫大小n
	for(int i=0; i<n; i++) // 循环读入迷宫
	{
		for(int j=0; j<n; j++)
		{
			cin>>bd[i][j];
		}
	}
	int sy, sx, ey, ex, flag=0; // 定义起点、终点和标志变量
	cin>>sy>>sx>>ey>>ex; // 输入起点和终点坐标
	re_bd[sy][sx] = 0; bd[sy][sx] = 1; // 初始化起点
	STU p, cur, f; p.y = sx; p.x = sy; // 初始化当前位置
	q.push(p); // 将起点入队
	while(!q.empty()) // 队列不空时循环
	{
		cur.y  = q.front().y;    cur.x  = q.front().x;    q.pop(); // 出队当前位置
		for(int i=0; i<8; i++) // 遍历八个方向
		{
			f.y = cur.y + help[i][0];    f.x = cur.x + help[i][1]; // 计算新位置
			
			if(bd[f.y][f.x] == 0) // 如果新位置可达
			{
				bd[f.y][f.x] = 1; // 标记新位置已访问
				q.push(f); // 新位置入队
				if(re_bd[f.y][f.x]==0) re_bd[f.y][f.x] = re_bd[cur.y][cur.x] + 1; // 更新最短路径值
			}
			else{
				continue; // 否则继续下一个方向
			}
			
			if(f.y == ey && f.x == ex) // 到达终点
			{
				printf("%d", re_bd[ey][ex]); // 输出最短路径长度
				flag = 1; break; // 设置标志并跳出循环
			}
		}
		if(flag == 1) break; // 如果已找到最短路径,跳出循环
	}
//被注释的代码可以输出re_bd的状态
//	for(int i=0; i<n; i++)
//	{
//		printf("\n");
//		for(int j=0; j<n; j++)
//		{
//			printf("%d ", re_bd[i][j]);
//		}
//		
//	}
	if(flag == 1) // 如果找到最短路径
	{
		stack<STU>s; // 定义栈s
		s.push(f); // 将终点入栈
		while(1) // 循环找到起点
		{
			cur.y = s.top().y; cur.x = s.top().x; // 获取栈顶元素
			if(cur.y == sy && cur.x == sx) break; // 到达起点,跳出循环
			for(int i=0; i<8; i++) // 遍历八个方向
			{
				f.y = cur.y + help[i][0]; 
				f.x = cur.x + help[i][1]; // 计算新位置
				int org = re_bd[cur.y][cur.x] - 1; // 原路径值
				int now = re_bd[f.y][f.x]; // 当前路径值
				if(org == 0) // 如果是起点
				{
					if(f.y == sy && f.x == sx) // 如果是起点
					{
						s.push(f); break; // 将起点入栈并跳出循环
					}
					continue; // 否则继续下一个方向
				}
				if( org == now && org != 0) // 如果是最短路径
				{
					s.push(f); break; // 将当前位置入栈并跳出循环
				} 
			}
			
 		}
 		printf("\n"); // 换行
 		for(; !s.empty(); ) // 输出路径
 		{
		 	printf("%d, %d; ", s.top().y, s.top().x); // 输出当前位置
		 	s.pop(); // 出栈
		 }
	}
	return 0; // 返回
}

易错点在于最短路径的回溯过程

回溯路径的原理:从出口开始,在re_bd(PS: re_bd[ i ][ j ]用来记忆从起点到第 i 行第 j 列的最短路径长度)里找周围八个方向中路径长度少1的点, 故一般情况可用以下代码非注释部分来判断

int org = re_bd[cur.y][cur.x] - 1; // 原路径值
int now = re_bd[f.y][f.x]; // 当前路径值
//if(org == 0) // 如果是起点
//{
//	if(f.y == sy && f.x == sx) // 如果是起点
//	{
//		s.push(f); break; // 将起点入栈并跳出循环
//	}
//	continue; // 否则继续下一个方向
//}
if( org == now && org != 0) // 如果是最短路径
{
	s.push(f); break; // 将当前位置入栈并跳出循环
} 

但是! 当要去寻找起点时,re_bd(起点) = 0!而且周围没有被走过的点都在一开始因为被初始化, 也全都是0!如此,则根本没有办法保证能成功找到起点。

解决方式:

1.补充上面被注释掉的“if(org == 0) // 如果是起点”部分, 将起点单独讨论

2.或者“见好就收”, 在re_bd == 1 时就结束寻找,在printf栈元素之前先print一下起点坐标

~如果对你有启发,还请点个赞告诉笔者哈~

关于re_bd的状态, 可以用加上下面的代码自行输出看看~

    for(int i=0; i<n; i++)
	{
		printf("\n");
		for(int j=0; j<n; j++)
		{
			printf("%d ", re_bd[i][j]);
		}
		
	}

~都看到这啦, 你一定是个超级认真的友友,关注一下吧~   

标签:bd,易错,cur,int,路径,sy,re,&&,起点
From: https://blog.csdn.net/H13420972436/article/details/137467525

相关文章

  • 最短路径问题
    1.最短路径问题如果从图中某一顶点(称为源点)到达另一顶点(称为终点)的路径可能不止一条,如何找到一条路径,使得沿此路径各边上的权值总和(即从源点到终点的距离)达到最小,这条路径称为最短路径(shortestpath)。根据有向网或无向网中各边权值的取值情形及问题求解的需要,最短路径问题分为......
  • 两个字符串间的最短路径问题【华为OD机试】(JAVA&Python&C++&JS题解)
    一.题目-两个字符串间的最短路径问题给定两个字符串,分别为字符串A与字符串B。例如A字符串为ABCABBA,B字符串为CBABAC可以得到下图m*n的二维数组,定义原点为(0,0),终点为(m,n),水平与垂直的每一条边距离为1,映射成坐标系如下图。从原点(0,0)到(0,A)为水平边,距离为1,从(0,A)......
  • 18天【代码随想录算法训练营34期】● 513.找树左下角的值 ● 112. 路径总和 113.路径
    513.找树左下角的值#Definitionforabinarytreenode.#classTreeNode:#def__init__(self,val=0,left=None,right=None):#self.val=val#self.left=left#self.right=rightclassSolution:deffindBottomLeftValue(self......
  • python 在命令行中选择文件路径的交互程序
    直接上代码,懒得多说1importcolorama2colorama.init()3fromcoloramaimportFore,Back,Style4importos5importre67class路径选择器:8def__init__(self):9当前路径=''10选择集=[]11路径深度......
  • nginx同一端口配置代理不同路径下的文件
    需求如下:CMS系统后台通过freemarker模板生成静态html文件,主站点和子站点的html文件保存在不同文件夹下。根据站点ID分别保存到不同文件夹,结构如下:  其中,75为主站点,111为子站点b。通过nginx配置,在同一域名下根据不同路径访问不同站点html。  实现访问www.xxx.com访问......
  • [1483. 树节点的第 K 个祖先] 【路径】
    思路很简单:importjava.util.ArrayList;importjava.util.List;classTreeAncestor{List<Integer>[]children;List<List<Integer>>paths=newArrayList<>();int[][]pathIdMap;publicstaticvoidmain(String[]args){......
  • C语言之易错知识点统计
    hello,铁汁们,大家好呀,我是脆皮炸鸡。今天是4,6号,发现了很多自己以前没有意识到的知识点误区,记录下来和大家分享一下,由于我的水平有限,难免会出错。若是有什么错误,恳请大家告知,在这里多谢大家啦!大家有什么易错点也可以在评论区分享一下呦。C语言规定,在一个源程序中,main函数......
  • 【MATLAB源码-第171期】基于matlab的布谷鸟优化算法(COA)无人机三维路径规划,输出做短路
    操作环境:MATLAB2022a1、算法描述布谷鸟优化算法(CuckooOptimizationAlgorithm,COA)是一种启发式搜索算法,其设计灵感源自于布谷鸟的独特生活习性,尤其是它们的寄生繁殖行为。该算法通过模拟布谷鸟在自然界中的行为特点,为解决各种复杂的优化问题提供了一种新颖的方法。从算法......
  • 17天【代码随想录算法训练营34期】第六章 二叉树part04(● 110.平衡二叉树 ● 257.
    110.平衡二叉树#Definitionforabinarytreenode.#classTreeNode:#def__init__(self,val=0,left=None,right=None):#self.val=val#self.left=left#self.right=rightclassSolution:defgetDepth(self,root):......
  • P4551 最长异或路径 题解
    题目链接:最长异或路径看到树上路径问题,且是异或和这种,先思考树上前缀和转化为前缀和问题。如果我们预处理出\(pre[curr]\)表示\(curr\)这个点到根的前缀异或值,那么很显然我们路径的两个点\(u\)与\(v\)的\(pre[u]\opluspre[v]\)和传统的加法的树上前缀和并不一样,因为异......