【兔年之兔子走迷宫】 用一个小游戏对回溯法进行实现 | C++

news2024/9/29 13:30:24

第六章    回溯法


目录

第六章    回溯法

●前言

●一、回溯法是什么?

1.简要介绍

●二、回溯法经典案例——兔子走迷宫游戏

1.具体情况

2.代码展示(C++)

3.结果展示 

●总结


前言

        简单的来说,算法就是用计算机程序代码来实现数学思想的一种方法。学习算法就是为了了解它们在计算机中如何演算,以及在当今的信息时代,它们是如何在各个层面上影响我们的日常生活的,从而提高我们的逻辑思维能力和处理实际问题的能力。善用算法、巧用算法,是培养程序设计逻辑的重中之重,许多实际的问题都可用多个可行的算法来解决, 但是要从中找出最优的解决算法却是一项挑战。


一、回溯法是什么?

1.简要介绍

        回溯法是枚举法的一种,它是一种可以找出所有解的一般性算法。同时为了避免枚举出现不正确的数值,发现错误值就停止向下一层运行,而是回溯到上一层。为了去减短时间和提高程序代码的执行效率,回溯法一般是一种走不通就退回另寻蹊径的方法。它的特点是在搜索过程中去寻找问题的解,发现不满足的答案就去回溯,从而去避免无效搜索。

二、回溯法经典案例——兔子走迷宫游戏

1.具体情况

        假如有一只兔子,我们去把它放到一个没有盖子的大迷宫盒中的起点,迷宫内有很多墙,从而使得大部分路径都被挡住而不能前行。兔子需要采用一种试错的方式去尝试走出迷宫,并且兔子需要在每次走错路时把走过的路记录下来,避免再次重复,直到最终到达终点。即①一次只能走一格;②遇到墙无法前行时回退一步去重新判断;③走过的路不会再走第二次;

        在程序中我们仿真迷宫的地图就用二维数组来抽象表示,用0去表示墙,用1表示通路。从而去创建一个12✖12大小的迷宫地图。如下图所示:

         兔子将会从起点maze[1][1]进入,从终点maze[9][10]出来,兔子当前的位置我们用maze[x][y]去表示。兔子在迷宫中可以选择的方向有四个,东、南、西、北。但并非每个位置此刻的兔子都可以去任意移动,需根据兔子所处在迷宫中的具体情况而定。从而我们可去创建一个老鼠移动的方位图。如下图所示:

         在该过程中我们将会用链表去对兔子走过的路径进行记录,并且将兔子走过的路径标记为2,再将其放入堆栈中,再去进行下一个方向的判断。由于每次每次新加入堆栈中的位置都会在其顶端,因此堆栈顶端指针指向的编号便是当前迷宫中兔子的位置。我们会将主要的算法写到类模块中,它主要用于去判断在当前位置的四个方位上是否存在前进的表格。若找到可前进的方格,则将该方格的编号记录到堆栈并且移动,反之则回溯进行重新的判断。

2.代码展示(C++)

        用程序代码去实现具体情况中的兔子走迷宫游戏。

#include<iostream>
using namespace std;
#define north maze[x-1][y]   //北
#define south maze[x+1][y]   //南
#define west maze[x][y-1]    //西
#define east maze[x][y+1]	 //东
int maze[12][12] = { {0,0,0,0,0,0,0,0,0,0,0,0},
					 {0,1,1,1,0,0,0,0,0,0,0,0},
					 {0,0,0,1,0,0,1,1,1,1,0,0},
					 {0,0,0,1,0,0,1,0,0,1,0,0},
					 {0,0,0,1,1,1,1,0,0,1,0,0},
					 {0,0,0,1,0,0,1,0,0,1,0,0},
					 {0,0,0,1,0,0,1,0,0,1,0,0},
					 {0,0,0,1,0,0,1,0,0,1,0,0},
					 {0,0,0,0,0,0,1,0,0,1,0,0},
					 {0,0,1,1,1,1,1,1,0,1,1,0},
					 {0,0,1,0,0,0,0,0,0,0,0,0},
					 {0,0,0,0,0,0,0,0,0,0,0,0} };  //二维数组迷宫图,0表示墙,1表示通路
const int exitx = 9, exity = 10;   //出口端在数组迷宫中的位置,9行10列

//链表的定义及其记录使用
struct list {
	int x, y;
	struct list* next;
};
typedef struct list node;
typedef node* link;
link push(link stack,int x,int y)
{
	link newnode;
	newnode = new node;
	if (!newnode)
	{
		return NULL;
	}
	newnode->x = x;
	newnode->y = y;
	newnode->next = stack;
	stack = newnode;
	return stack;
}
link pop(link stack, int *x, int *y)
{
	link top;
	if (stack != NULL)
	{
		top = stack;
		stack=stack->next;
		*x= top->x;
		*y = top->y;
		delete top;
		return stack;
	}
	else
	{
		*x = -1;
	}
	return stack;
}
//

int checkexit(int x,int y)  //检查是否到达终点
{
	if (x == exitx && y == exity)
		return 1;
	else
		return 0;
}

class maze_data {
public:
	int x;
	int y;
	void walk_judgement()
	{
		link path = NULL;   //初始化路径
		while (x <= exitx && y <= exity)   //while循环中进行东南西北四个方位移动的判断
		{
			maze[x][y] = 2;
			if (north == 1)  //上一格可走
			{
				x--;  //往上走
				path = push(path, x, y);  //加入方格编号到对堆栈
			}
			else if (south == 1)  //下一个可走
			{
				x++;   //往下走
				path = push(path, x, y); //加入方格编号到对堆栈
			}
			else if (west == 1)   //左一格可走
			{
				y--;   //往左走
				path = push(path, x, y); //加入方格编号到对堆栈
			}
			else if (east == 1)    //右一格可走
			{
				y++;   //往右走
				path = push(path, x, y); //加入方格编号到对堆栈
			}
			else if (checkexit(x, y) == 1)  //如果判断到已经到达终点,从而跳出循环
				break; 
			else    //记录走过的位置
			{
				maze[x][y] = 2;
				path = pop(path, &x, &y);
			}
		}
	}
};
void text1()
{
	cout << "-----------------------" << endl;
	for (int i = 0; i < 12; i++)
	{
		for (int j = 0; j < 12; j++)
		{
			cout << maze[i][j] << " ";
		}
		cout << endl;
	}
	cout << "-----------------------" << endl;
}
void text2()
{
	maze_data md;
	md.x = 1;
	md.y = 1;
	md.walk_judgement();
}
int main()
{
	text1();  //输出初始的迷宫矩阵
	text2();  
	text1();  //输出最终老鼠走过路径的迷宫矩阵
}

3.结果展示 

图一

图二

总结

        在以上我们通过一个兔子走迷宫游戏案例,对回溯法进行了实现。其实回溯法应该很广泛的运用到我们的程序代码中,它是一种很好的算法编程思想。大家也可以对我上面的代码进行二次修改,从而去实现一个更大的迷宫地图、更复杂路径和过程的迷宫小游戏。今天刚好是大年除夕,博主在这里给大家拜年了!祝福大家阖家欢乐,兔年大吉!事业“兔”飞猛进,财富“兔”然斗增!身体蹦蹦跳跳健康平安。

                                               <您的三连和关注是我最大的动力>

                       🚀 文章作者:Keanu Zhang        分类专栏:算法之美(C++系列文章)

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/174576.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

性能监控和工具使用

1、jvm 内存模型 程序计数器 Program Counter Register&#xff1a;  记录的是正在执行的虚拟机字节码指令的地址&#xff0c;  此内存区域是唯一一个在JAVA虚拟机规范中没有规定任何OutOfMemoryError的区 域  虚拟机&#xff1a;VM Stack  描述的是 JAVA 方法执行的内…

Delphi 中.dproj 文件解析(二、详细解析)

上一篇 介绍了Delphi 的各个版本&#xff0c;本文开始分析.dproj文件。.dproj是一个XML文件&#xff0c;里边包含了我们在Delphi开发环境中对项目设置的所有参数&#xff08;位于IDE&#xff1a;Project -> Options 中&#xff09;&#xff0c;包括并不限于&#xff1a;版本…

LabVIEW查找范例VI

LabVIEW查找范例VILabVIEW拥有数百个范例VI&#xff0c;用户可搜索需要的范例VI并将其整合到自己创建的VI中。除LabVIEW内置的范例VI之外&#xff0c;在ni.com技术支持页中可查看更多的范例VI。用户可根据应用程序的需要对范例进行修改&#xff0c;也可复制并粘贴一个或多个范例…

LC-1824. 最少侧跳次(动态规划)

1824. 最少侧跳次数 难度中等49 给你一个长度为 n 的 3 跑道道路 &#xff0c;它总共包含 n 1 个 点 &#xff0c;编号为 0 到 n 。一只青蛙从 0 号点第二条跑道 出发 &#xff0c;它想要跳到点 n 处。然而道路上可能有一些障碍。 给你一个长度为 n 1 的数组 obstacles &a…

【FPGA】Verilog 实践:狄摩根定律 | 布尔方程 | 1bit 比较器

写在前面&#xff1a;为了解狄摩根定理和布尔函数的行为&#xff0c;我们使用 Verilog 实现狄摩根定律和布尔函数的行为。生成输入信号后&#xff0c;验证通过仿真实现的结果。 Ⅰ. 前置知识 0x00 离散结构&#xff1a;否定量词的狄摩根定律 否定量词的狄摩根定律是&#xf…

基于自适应降噪的深度神经网络对抗图像检测【论文阅读】

近年来&#xff0c;许多研究表明&#xff0c;深度神经网络(DNN)分类器可能会被对抗性示例所欺骗&#xff0c;这种对抗性示例是通过对原始样本引入一些扰动来设计的。据此&#xff0c;提出了一些强大的防御技术。然而&#xff0c;现有的防御技术往往需要修改目标模型或依赖于攻击…

针对容器场景的多功能渗透工具

介绍 CDK是一款为容器环境定制的渗透测试工具&#xff0c;在已攻陷的容器内部提供零依赖的常用命令及PoC/EXP。集成Docker/K8s场景特有的 逃逸、横向移动、持久化利用方式&#xff0c;插件化管理。 下载/植入 将可执行文件投递到已攻入的容器内部开始使用 https://github.c…

浏览器打不开某些网站是什么原因导致,试试用这些方法来解决

不少小伙伴使用一些浏览器浏览网页的时候&#xff0c;发现打不开某些网站&#xff0c;这是什么原因导致的呢?本文讲汇总几个常见的原因&#xff0c;我们可以通过以下几个原因排查&#xff0c;并且使用下文的解决方法可以试试能否打开网站。打不开网站的原因1、浏览器限制如果用…

SpringMVC工作流程

SpringMVC工作流程 1. SpingMVC的常用组件 1&#xff09;DispatcherServlet 是一种前端控制器&#xff0c;由框架提供。作用&#xff1a;统一处理请求和响应。除此之外还是整个流程控制的中心&#xff0c;由 DispatcherServlet 来调用其他组件&#xff0c;处理用户的请求 2&am…

在甲骨文云容器实例(Container Instances)上部署Oracle Linux 8 Desktop

甲骨文云推出了容器实例&#xff0c;这是一项无服务器计算服务&#xff0c;可以即时运行容器&#xff0c;而无需管理任何服务器。 今天我们尝试一下通过容器实例部署Oracle Linux 8 Desktop。 创建容器实例 在甲骨文容器实例页面&#xff0c;单击"创建容器实例"&am…

【甄选靶场】Vulnhub百个项目渗透——项目五十六:sp-jerome(squid代理,计划任务)

Vulnhub百个项目渗透 Vulnhub百个项目渗透——项目五十六&#xff1a;sp-jerome&#xff08;文件上传&#xff0c;缓冲区溢出&#xff09; &#x1f525;系列专栏&#xff1a;Vulnhub百个项目渗透 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4…

微信公众号主体已注销 如何办理账号迁移和公证书?

公众号主体公司已经注销&#xff0c;公众号也可以办理迁移的。而且需要尽快迁移&#xff0c;如果被微信系统检测到主体注销&#xff0c;而公众号还在经营就会要求限期迁移&#xff0c;否则公众号将被冻结。 下面我们就来说一下&#xff0c;主体已注销如何办理公众号迁移。 注&a…

Ubuntu20.04+GLFW搭建OpenGL开发环境

环境 系统&#xff1a;Ubuntu 20.04 桌面环境&#xff1a;X11 OpenGL版本: 3.0 桌面环境怎么看呢&#xff1f;可以在终端输入echo $XDG_SESSION_TYPE 即可&#xff0c;或者查看桌面右上角的Settings->About&#xff0c;查看Windowing System 查看OpenGL版本 使用glxinfo命…

【数据结构】深度剖析栈的各接口功能实现

目录 &#x1f34a;前言&#x1f34a;&#xff1a; &#x1f95d;一.栈的概述&#x1f95d;&#xff1a; 1.栈的概念&#xff1a; 2.栈的结构&#xff1a; &#x1f349; 二、栈的各接口功能实现&#x1f349;&#xff1a; 1.栈的初始化&#xff1a; 2.压栈&#xff1a;…

十六进制转八进制(蓝桥杯基础练习C/C++)

我首先想到的就是十六进制转十进制&#xff0c;十进制转八进制&#xff0c;毕竟这样的方法是最常见的&#xff0c;但始终出现报错。 我想可能是int能储存的数范围太小了&#xff0c;就尝试用long long存储&#xff0c;结果还是报错。 #include <bits/stdc.h> using nam…

C++语法复习笔记-1. c++指针

文章目录1. 计算机内存1. 储存层次2. 内存单元与地址3. 指针定义2. 左值与右值1. 数组与指针1. 概念3. C中的原始指针1. 数组指针与指针数组2. const pointer 与 pointer to const3. 指向指针的指针4.关于野指针4.1 指向指针的指针4.2 NULL指针4.3 野指针5. 指针的基本运算5.1 …

Linux基础 IO

目录 一、文件操作 1.1 C语言文件操作 1.2 文件 系统调用接口 1.2.1 open/close函数 1.2.2 write/read函数 二、进程与文件 2.1 0&1&2 文件描述符 2.2 C语言FILE 2.3 (OS管理&进程找到) 被打开文件方法 2.3.1 struct file 描述文件属性(OS管理文件) 2.3…

线性时变系统的PID控制-2

在线性时变系统的PID控制-1的基础上采用S函数进行Simulink仿真。被控对象的描述方式可变换为&#xff1a;在S函数中&#xff0c;采用初始化、微分函数和输出函数&#xff0c;即mdllnitializeSizes函数、mdIDerivatives函数和mdlOutputs函数。在初始化中采用sizes结构&#xff0…

力扣sql简单篇练习(三)

力扣sql简单篇练习(三) 1 查找重复的电子邮箱 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 SELECT Email FROM Person GROUP BY Email HAVING count(id)>21.3 运行截图 2 每个产品在不同商店的价格 2.1 题目内容 2.1.1 基本题目信息 2.1.2 示…

[经典的图像warping方法] Thin Plate Spline: TPS理论和代码详解

0. 前言 2022年没有新写什么博客, 主要精力都在搞论文. 今年开始恢复! 本文的目标是详细分析一个经典的基于landmark(文章后面有时也称之为控制点control point)的图像warping(扭曲/变形)算法: Thin Plate Spine (TPS). TPS被广泛的应用于各类的任务中, 尤其是生物形态中应用…