【回溯算法】n-皇后

导航

    • 题目来源
    • 题目描述
    • 示例
    • 思路
    • 完整代码

题目来源

n-皇后

题目描述

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。

n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

给你一个整数 n ,返回所有不同的n 皇后问题的解决方案。

每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中'Q' 和 '.'分别代表了皇后和空位。

示例

在这里插入图片描述

思路

这道题是根据labuladong算法秘籍刷到的

回溯的过程可以看作是决策树中做决策与撤回决策,决策就是走向下一层,撤回决策就是返回。
在这里插入图片描述

核心代码:

void backtrack(当前选择, 剩余选择列表) {if (当前选择产生的结果满足结束递归条件) {return;}for (选择 in 剩余选择列表) {//做出当前选择st[选择] = true;// 进入下一层决策树backtrack(选择 ,剩余选择列表);// 撤回选择st[选择] = false;}
}
  • 在本题中决策树的每一层表示棋盘上的每一行;每个节点可以做出的选择是,在该行的任意一列放置一个皇后。
  • 回溯的过程中,当前考虑行的前面所有行已经做过选择

回溯函数

/**@description: 回溯函数,如果当前递归到row行,前row-1行已经放置好皇后@param: borad - 棋盘@param: row - 当前到第几行了*/void backtrack(vector<string> &borad, int row) {if (row == borad.size()) {res.push_back(borad);return;}int n = borad[row].size();for (decltype(borad.size()) i = 0; i < n; ++ i) {// 判断row 行 i 列可不可以放皇后if (!valid(borad, row, i)) {// 不能放continue;}// 放置皇后borad[row][i] = 'Q';// 继续下一行棋盘backtrack(borad, row + 1);// 不放borad[row][i] = '.';}}

valid函数用于判断当前位置是否可以放置皇后:
如果当前位置所在行、列、正对角线、负对角线有放置皇后,那么当前位置就不可以放置皇后了

valid函数

/**@param: board  棋盘@param: row  行@param: line 列@return bool类型,true表示可以放,false表示不可以放*/bool valid(vector<string> &board, int row, int line) {int n = board.size();// 同一行是否放了皇后for (int j = 0; j < line; ++ j) {if (board[row][j] == 'Q') return false;}// 同一列是否放了皇后for (int i = 0; i < row; ++ i) {if (board[i][line] == 'Q') return false;}// 左斜线是否放了皇后int b = line - row;for (int i = 0; i < row; ++i) {int j = i + b;if (j < 0) continue;if (board[i][j] == 'Q') return false;}// 右斜线是否放了皇后b = row + line;for (int i = 0; i < row; ++ i) {int j = b - i;if (j < 0) continue;if (board[i][j] == 'Q') return false;}// 都没有放皇后return true;}

这里解释一下为什么正对角、负对角这么计算:将棋盘想象成下面样子
在这里插入图片描述

正对角的情况如下:
在这里插入图片描述
对于当前位置(row, line),我们可以确定这条对角线:计算b = y - x;
所以b = line - row, 然后从 0 ~ row - 1 计算每一个 y值, 然后要保证y值为正

负对角同理

完整代码

class Solution {
public:vector<vector<string>> res;vector<vector<string>> solveNQueens(int n) {vector<string> borad(n, string(n, '.'));// 回溯backtrack(borad, 0);return res;}/**@description: 回溯函数,如果当前递归到row行,前row-1行已经放置好皇后@param: borad - 棋盘@param: row - 当前到第几行了*/void backtrack(vector<string> &borad, int row) {if (row == borad.size()) {res.push_back(borad);return;}int n = borad[row].size();for (decltype(borad.size()) i = 0; i < n; ++ i) {// 判断row 行 i 列可不可以放皇后if (!valid(borad, row, i)) {// 不能放continue;}// 放置皇后borad[row][i] = 'Q';// 继续下一行棋盘backtrack(borad, row + 1);// 不放borad[row][i] = '.';}}/**@param: board  棋盘@param: row  行@param: line 列@return bool类型,true表示可以放,false表示不可以放*/bool valid(vector<string> &board, int row, int line) {int n = board.size();// 同一行是否放了皇后for (int j = 0; j < line; ++ j) {if (board[row][j] == 'Q') return false;}// 同一列是否放了皇后for (int i = 0; i < row; ++ i) {if (board[i][line] == 'Q') return false;}// 左斜线是否放了皇后int b = line - row;for (int i = 0; i < row; ++i) {int j = i + b;if (j < 0) continue;if (board[i][j] == 'Q') return false;}// 右斜线是否放了皇后b = row + line;for (int i = 0; i < row; ++ i) {int j = b - i;if (j < 0) continue;if (board[i][j] == 'Q') return false;}// 都没有放皇后return true;}
};

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

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

相关文章

【Linux Shell】9. 流程控制

文章目录 【 1. if else 判断 】1.1 if1.2 if else1.3 if elif else1.4 实例 【 2. case 匹配 】【 3. 循环 】3.1 for 循环3.2 while 循环3.3 until 循环3.4 无限循环3.5 跳出循环3.5.1 break 跳出所有循环3.5.2 continue 仅跳出当前循环 【 1. if else 判断 】 1.1 if fi 是…

【算法】递归算法理解(持续更新)

这里写目录标题 一、递归算法1、什么情况下可以使用递归&#xff1f;2、递归算法组成部分3、案例&#xff1a;求n的阶乘4、编写一个递归函数来计算列表包含的元素数。5、通过递归找到列表中最大的数字。6、通过递归的方式实现二分查找算法。 一、递归算法 递归&#xff08;Rec…

“单项突出”的赢双科技IPO加速,比亚迪是最强助力?

近日&#xff0c;新能源汽车核心部件供应商赢双科技首次递表科创板&#xff0c;其凭借旋转变压器产品就坐稳了新能源车企主要供应商的地位&#xff0c;从核心业务及业绩情况来看&#xff0c;赢双科技不愧为“单项冠军”。 据悉&#xff0c;赢双科技本次IPO拟募资8.47亿元&…

3.9 EXERCISES

矩阵加法需要两个输入矩阵A和B&#xff0c;并产生一个输出矩阵C。输出矩阵C的每个元素都是输入矩阵A和B的相应元素的总和&#xff0c;即C[i][j] A[i][j] B[i][j]。为了简单起见&#xff0c;我们将只处理元素为单精度浮点数的平方矩阵。编写一个矩阵加法内核和主机stub函数&am…

P9 视频码率及其码率控制方式

前言 从本章开始我们将要学习嵌入式音视频的学习了 &#xff0c;使用的瑞芯微的开发板 &#x1f3ac; 个人主页&#xff1a;ChenPi &#x1f43b;推荐专栏1: 《C_ChenPi的博客-CSDN博客》✨✨✨ &#x1f525; 推荐专栏2: 《Linux C应用编程&#xff08;概念类&#xff09;_C…

一款开源的MES系统

随着工业4.0的快速发展&#xff0c;制造执行系统&#xff08;MES&#xff09;成为了智能制造的核心。今天&#xff0c;将为大家推荐一款开源的MES系统——iMES工厂管家。 什么是iMES工厂管家 iMES工厂管家是一款专为中小型制造企业打造的开源MES系统。它具备高度的可定制性和灵…

Jenkins集成部署java项目

文章目录 Jenkins简介安装 Jenkins简介 Jenkins能实时监控集成中存在的错误&#xff0c;提供详细的日志文件和提醒功能&#xff0c;还能用图表的形式形象的展示项目构建的趋势和稳定性。 官网 安装 在官网下载windows版本的Jenkins 但是我点击这里浏览器没有反应&#xff0…

关于自增和自减的一些细节问题

目录 基本概念 1.运算 2.输出 基本概念 在这里简单回顾一下自增和自减&#xff1a;顾名思义&#xff0c;自就是同一变量的值发生变化&#xff0c;自增就是该变量值加1&#xff0c;自减就是该变量值减1。 自增和自减又可以根据运算符的位置不同分为前缀式和后缀式。前缀就是…

hfish蜜罐docker部署

centos 安装 docker-CSDN博客Docker下载部署 Docker是我们推荐的部署方式之一&#xff0c;当前的版本拥有以下特性&#xff1a; 自动升级&#xff1a;每小时请求最新镜像进行升级&#xff0c;升级不会丢失数据。数据持久化&#xff1a;在宿主机/usr/share/hfish目录下建立dat…

Unity 使用Sprite绘制一条自定义图片的线

Unity 使用Sprite绘制一条自定义图片的线 前言项目场景布置代码编写总结 运行效果感谢 前言 遇到一个需要绘制自定义形状的需求。那只能利用Sprite来绘制一条具有自定义图片的线&#xff0c;通过代码动态设置起点、终点以及线宽&#xff0c;实现灵活的线条效果。 项目 场景…

2024.1.3力扣每日一题——从链表中移除节点

2024.1.3 题目来源我的题解方法一 递归方法二 栈方法三 反转链表方法四 单调栈头插法 题目来源 力扣每日一题&#xff1b;题序&#xff1a;2487 我的题解 方法一 递归 当前节点对其右侧节点是否删除无影响&#xff0c;因此可以对其右侧节点进行递归移除。 若当前节点为空&am…

BLE Mesh蓝牙组网技术详细解析之Access Layer访问层(六)

目录 一、什么是BLE Mesh Access Layer访问层&#xff1f; 二、Access payload 2.1 Opcode 三、Access layer behavior 3.1 Access layer发送消息的流程 3.2 Access layer接收消息的流程 3.3 Unacknowledged and acknowledged messages 3.3.1 Unacknowledged message …

Python selenium实现断言3种方法解析

1.if ...else ...判断进行断言 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 from time import * from selenium import webdriver def login(user"admin",pwd"123456"): driver webdriver.Chrome() driver.implicitly_wait(10)…

RedisInsight - Redis官方可视化工具

一、RedisInsight 简介 RedisInsight 是一个直观高效的 Redis GUI 管理工具&#xff0c;它可以对 Redis 的内存、连接数、命中率以及正常运行时间进行监控&#xff0c;并且可以在界面上使用 CLI 和连接的 Redis 进行交互&#xff08;RedisInsight 内置对 Redis 模块支持&#…

C语言--结构体详解

C语言--结构体详解 1.结构体产生原因2.结构体声明2.1 结构体的声明2.2 结构体的初始化2.3结构体自引用 3.结构体内存对齐3.1 对齐规则3.2 为什么存在内存对齐3.3 修改默认对⻬数 4. 结构体传参 1.结构体产生原因 C语言将数据类型分为了两种&#xff0c;一种是内置类型&#xf…

防火安全球阀,到2027年市场增长至68亿美元

防火安全球阀是一种在火灾、爆炸等危险环境下仍能正常使用的阀门。它被广泛用于石化、化工、船舶、电力等领域&#xff0c;以保障生产和人员安全。下面我们将从全球市场和中国市场两个方面对其发展趋势进行分析。全球市场分析&#xff1a; 从全球市场的角度来看&#xff0c;防火…

软件测试|Linux基础教程:ln命令与软链接和硬链接

简介 在Linux系统中&#xff0c;ln命令是一个非常有用的工具&#xff0c;用于创建链接&#xff08;link&#xff09;&#xff0c;将一个文件或目录链接到另一个位置。链接允许一个文件或目录可以同时存在于多个位置&#xff0c;而不会占用额外的磁盘空间。ln命令支持创建硬链接…

UI5与后端的文件交互(四)

文章目录 前言一、后端开发1. 新建管理模板表格2. 新建Function&#xff0c;动态创建文档 二、修改UI5项目1.Table里添加下载证明列2. 实现onClickDown事件 三、测试四、附 前言 这系列文章详细记录在Fiori应用中如何在前端和后端之间使用文件进行交互。 这篇的主要内容有&…

Unity 打包AB 场景烘培信息丢失

场景打包成 AB 资源的时候&#xff0c;Unity 不会打包一些自带相关的资源 解决办法&#xff1a;在 Project settings > Graphics下设置&#xff08;Automatic 修改成 Custom&#xff09;

selenium对于页面改变的定位元素处理办法

在学习selenimu中&#xff0c;总是发现元素定位不到&#xff0c;想了各种办法&#xff0c;最后总结大致有两个原因。 1.等待时间不够&#xff0c;页面还没有完全渲染就进行操作&#xff0c;使用time模块进行等待。 2.换了页面后&#xff0c;发现定位不到元素&#xff0c;因为…