Python 递归、迷宫问题、八皇后问题

递归应用场景

  • 各种数学问题,如八皇后问题、汉诺塔、阶乘问题、迷宫问题、球和篮子问题等
  • 各种算法中也会使用到递归,比如快排、归并排序、二分查找、分治算法等
  • 能够用栈解决的问题
  • 递归的优点就是代码比较简洁

迷宫问题(Python版)

迷宫示意图, 红色部分表示墙,绿色部分表示通路,第一张图为初始迷宫,第二张为回溯之后的迷宫

      

代码实现

class MiGong:def __init__(self):# 创建一个 8*7 嵌套列表,模拟迷宫self.map = []row = 8col = 7# 初始化迷宫# 1表示墙,0表示可通行# 将第0行设置为墙for i in range(row):ls = []for j in range(col):if i == 0 or i == 7 or j == 0 or j == 6:ls.append(1)else:ls.append(0)self.map.append(ls)self.map[3][1] = 1self.map[3][2] = 1self.map[4][3] = 1self.print_map()# 打印迷宫def print_map(self):row = len(self.map)col = len(self.map[0])for i in range(row):for j in range(col):print(self.map[i][j], end=' ')print()print()def find_way(self, i: int, j: int) -> True:"""map: 表示迷宫地图(i, j): 老鼠的起始位置map[i][j] = 0: 表示该位置没有走过map[i][j] = 1: 表示该位置是墙(走不了)map[i][j] = 2: 表示该位置是通路(可以走)map[i][j] = 3: 表示这个位置是死路上的一个节点(走不了)寻路策略:下 -> 右 -> 上 -> 左map[6][5] = 2 表示走到了终点(终点位置为(6,5))"""if self.map[6][5] == 2:return Trueelse:if self.map[i][j] == 0:# 假设可以走通,先设为2self.map[i][j] = 2if self.find_way(i + 1, j):  # 向下走return Trueelif self.find_way(i, j + 1):  # 向右走return Trueelif self.find_way(i - 1, j):  # 向上走return Trueelif self.find_way(i, j - 1):  # 向左走return Trueelse:  # 死路,走不通,设为3self.map[i][j] = 3return Falseelse:  # self.map[i][j] == 1,2,3 ,都表示走不通或已走过return Falsemg = MiGong()
mg.find_way(1, 1)
mg.print_map()

八皇后问题

思路分析

1、先将第一个皇后放在第一行第一列的位置
2、第二个皇后先放在第二行第一列的位置,然后判断是否冲突,如果冲突,则放在第二行第二列,继续判断,如果冲突,将第二个皇后放在第二行第三列... 依次把第二行所有列都尝试一遍,直到找到合适的一列,摆放第二个皇后
3、接着摆放第三个皇后,依次尝试放在第三行的第一列、第二列、第三列...直到找到一个合适的列摆放第三个皇后
4、同样的摆放第四个、第五个、第六个、第七个、第八个皇后,当第八个皇后也放到第八行的正确位置时,此时找到了一个正确解
5、当第八个皇后摆放好后,即第八个皇后第一次找到正确的位置后,开始回溯,查找其他摆放方法,即将第一个皇后放在第一行第一列这个位置上的所有正确解找出来
6、然后将第一个皇后放在第一行第二列的位置,重复 2-5 的步骤
7、依次将第一个皇后放在第一行第三、四、五、六、七、八列的位置,重复 2-5 的步骤,得到八皇后问题的全部解法(92)说明:理论上棋盘应该是一个二维数组,但是实际上可以通过算法,用一个一维数组解决,一维数组的下标对应行标,数组的元素对应列标,如 arr[8] = [0, 4, 7, 5, 2, 6, 1, 3] 表示:第一个皇后放在第 0 行 第 0 列的位置第二个皇后放在第 1 行 第 4 列的位置第三个皇后放在第 2 行 第 7 列的位置第四个皇后放在第 3 行 第 5 列的位置第五个皇后放在第 4 行 第 2 列的位置第六个皇后放在第 5 行 第 6 列的位置第七个皇后放在第 6 行 第 1 列的位置第八个皇后放在第 7 行 第 3 列的位置
即 arr[i] = val 表示第 i 个皇后摆放的位置是第 i 行 第 val 列

代码实现

class Queen:count = 0  # 全部的正确解def __init__(self, num: int):self.num = num  # 皇后的数量# 用列表表示一维数组,记录皇后摆放的正确位置self.arr = []# 初始化数组for i in range(num):self.arr.append(-1)def check_position(self, n: int) -> bool:"""摆放第 n 个皇后在某个位置时,判断是否与前面的 n-1 皇后产生冲突,不冲突返回Truen 从 0 开始"""for i in range(n):# arr[i] = val 表示第 i 个皇后摆放的位置是第 i 行 第 val 列if self.arr[i] == self.arr[n]:  # 有两个皇后在同一列return False# if n - i == self.arr[n] - self.arr[i]:  # 有两个皇后在正对角线上#     # 正对角线判断:x2 - x1 == y2 - y1#     # (x1, y1) = (i, self.arr[i])#     # (x2, y2) = (n, self.arr[n])#     return False# if n - i == self.arr[i] - self.arr[n]:  # 有两个皇后在反对角线上#     # 反对角线上判断:x2 - x1 == y1 - y2#     # (x1, y1) = (i, self.arr[i])#     # (x2, y2) = (n, self.arr[n])#     return False# 合并在一起写if abs(n - i) == abs(self.arr[n] - self.arr[i]):  # 有两个皇后在对角线上return Falsereturn Truedef place_queen(self, n: int):"""放置第 n 个皇后,n 从0开始"""if n == self.num:  # 全部皇后已经放完,得到一个正确解self.count += 1print(f'第{self.count}种的解法为{self.arr}')return# 从第 n 行的第一列开始,依次尝试放置这第 n 个皇后,# 看哪个位置可以放,即不会与前面的 n-1 个皇后产生冲突for i in range(self.num):  # i 表示列数self.arr[n] = i  # 把第 n 个皇后放置在第 n 行第 i 列# 检查把第 n 个皇后放置在第 n 行第 i 列后是否与前面的 n-1 个皇后产生冲突if self.check_position(n):  # 不产生冲突# 如果不产生冲突,则确定了该皇后的放置位置,则开始放置下一个皇后self.place_queen(n + 1)# 如果冲突,标明第 n 行的第 i 列不能放,继续尝试第 i+1 列def print_arr(self):"""打印数组"""for i in self.arr:print(i, end=' ')print()q = Queen(8)
q.place_queen(0)  # 从第一个皇后开始,从 0 开始
print('八皇后的全部解法有%s种' % q.count)

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker 的常用命令

0 基本命令 概述 [root192 home]# docker --helpUsage: docker [OPTIONS] COMMANDA self-sufficient runtime for containersOptions:--config string Location of client configfiles (default "/root/.docker")-c, --context string Name of the context…

JAVA毕业设计097—基于Java+Springboot+Vue+uniapp的医院挂号小程序系统(源码+数据库)

基于JavaSpringbootVueuniapp的医院挂号小程序系统(源码数据库)097 一、系统介绍 本系统前后端分离(网页端和小程序端都有) 本系统分为管理员、医院、用户三种角色(角色菜单可自行分配) 用户功能: 注册、登录、医院搜索、最新资讯、医生搜索、挂号预约、挂号记…

【Springcloud】elk分布式日志

【Springcloud】elk分布式日志 【一】基本介绍【二】Elasticsearch【1】简介【2】下载【3】安装【4】启动 【三】Logstash【1】简介【2】下载【3】安装【4】启动 【四】Kibana【1】简介【2】下载【3】安装【4】启动 【五】切换中文【六】日志收集 【一】基本介绍 (…

【Linux从入门到精通】通信 | 共享内存(System V)

本篇文章接着上篇文章通信 | 管道通信(匿名管道 & 命名管道)进行讲解。本篇文章的中点内容是共享内存。 文章目录 一、初识与创建共享内存 1、1 什么是共享内存 1、2 共享内存函数 1、2、1 创建共享内存 shmget 1、2、2 ftok 生成 key 1、2、3 获取共…

C#__多线程之任务和连续任务

/// <summary> /// /// 任务&#xff1a;System.Threading.Tasks&#xff08;异步编程的一种实现方式&#xff09; /// 表应完成某个单元工作。这个工作可以在单独的线程中运行&#xff0c;也可以以同步方式启动一个任务。 /// /// 连续任务&#…

华为云云耀云服务器L实例评测|在 Centos Docker 中使用Nginx部署Vue项目

目录 前言 项目构建 使用CentOS部署 安装Nginx 配置Nginx 项目启动 访问重定向 使用Docker部署 编写docker文件 dockerfile nginx dockercompose 项目启动 前言 本期我们测试在云耀云服务器L实例中分别演示如何在 系统镜像Centos 与 应用镜像 Docker 中使用Nginx…

前端js下载zip文件异常问题解决

目录 一&#xff0c;本文解决问题如下 二&#xff0c;原下载代码 1&#xff0c;ajax get 下载文件 2&#xff0c;下载异常图&#xff1a; 三&#xff0c;成功下载的 1&#xff0c; JQuery 实现文件下载xhr 2&#xff0c;图例 引言&#xff1a; 本人使用的ajax 下载&…

geopandas 笔记:geometry上的操作汇总

如无特殊说明&#xff0c;数据主要来自&#xff1a;GeoDataFrame 应用&#xff1a;公园分布映射至subzone_UQI-LIUWJ的博客-CSDN博客 0 读入数据 subzone gpd.read_file(ura-mp19-subzone-no-sea-pl.geojson) subzone subzone_tstsubzone[0:5] subzone_tst subzone_tst.plot…

iOS App上架新规解析:如何进行App备案

摘要 本文将以iOS技术博主的身份&#xff0c;解析iOS App上架新规中的App备案要求。通过探讨备案对开发者和市场的影响&#xff0c;介绍备案流程和所需材料&#xff0c;帮助开发者了解如何进行App备案。 引言 近年来&#xff0c;移动应用市场蓬勃发展&#xff0c;但同时也存…

elasticsearch wildcard 慢查询原因分析(深入到源码!!!)

大家好&#xff0c;我是蓝胖子&#xff0c;前段时间线上elasticsearch集群遇到多次wildcard产生的性能问题&#xff0c; elasticsearch wildcard 一直是容易引发elasticsearch 容易宕机的一个风险点&#xff0c; 但究竟它为何消耗cpu呢&#xff1f;又该如何理解elasticsearch p…

Java网络编程(二)Socket 套接字(TCP和UDP),以及TCP的回显

Socket 套接字 我们软件工作者&#xff0c;着重编写的是应用层的代码&#xff0c;但是发送这个数据&#xff0c;我们就需要将应用层传输到传输层&#xff0c;也就意味着我们需要调用应用层的API&#xff0c;统称为 Socket API。 套接字的分类&#xff1a; 流套接字&#xff…

JetBrains设置文件名格式

如题&#xff0c;在使用CLion创建C类时&#xff0c;希望创建的文件名符合Google编码规范。设置如下图所示&#xff1a; 创建的C类是PascalCase格式&#xff0c;对应的文件名是pascal-case格式。