n-皇后问题(DFS回溯)

n−皇后问题是指将 n 个皇后放在 n×n的国际象棋棋盘上,使得皇后不能相互攻击到,即任意两个皇后都不能处于同一行、同一列或同一斜线上。

1_597ec77c49-8-queens.png

现在给定整数 n,请你输出所有的满足条件的棋子摆法。

输入格式

共一行,包含整数 n。

输出格式

每个解决方案占 n 行,每行输出一个长度为 n 的字符串,用来表示完整的棋盘状态。

其中 . 表示某一个位置的方格状态为空,Q 表示某一个位置的方格上摆着皇后。

每个方案输出完成后,输出一个空行。

注意:行末不能有多余空格。

输出方案的顺序任意,只要不重复且没有遗漏即可。

数据范围

1≤n≤9

输入样例:
4
输出样例:
.Q..
...Q
Q...
..Q...Q.
Q...
...Q
.Q..

国际象棋中的皇后可以直接攻击到她所在的行,列,斜方向上的棋子

思路:这道题也是使用DFS来求解的,关于DFS与递归的问题可以先看我的上一篇文章,有图解:排列数字(DFS深度优先搜索)-CSDN博客

一开始想的办法就是遍历枚举每一种情况,第一行第一列放皇后,之后如何,第二行第二列放皇后,之后如何,但是这样太繁琐了。

不妨每次只看一行的情况,遍历这一行上的每一列,如果当前位置可以放则放下皇后,然后进入下一行,再次枚举放皇后,直到每一行都放好了皇后,这时候便得到了一种可行的摆法,最开始是第一行第一列放皇后,得到解之后或者位置矛盾就回溯(return和if循环),第一行第二列放皇后,以此类推。

回溯则是从终止的那一列开始的(已经输出或者位置矛盾不能放),因为每一列都有一个for循环,所以当前列终止之后会自动执行上一列的for循环(如果还能循环的话),也就是我们所谓的回到上一列继续枚举,如果全部执行完毕就得到了全部结果。

这是DFS的代码:

void dfs(int u) //u表示行,输出每一行皇后的位置
{if( u == n ) //到最后一个位置的下一位(所有位置都填满了){for(int i=0;i<n;i++) puts(g[i]); //输出第i行的棋盘状态,g是二维数组,这样是按行输出puts("");return;}for(int i=0;i<n;i++) //对于一行,枚举每一列的情况{//行是u,列是i//dg下标n-u+i,udg下标u+i,如果下标相同就说明是同一条对角线if(!col[i] && !dg[n+u-i] && !udg[u+i]) //如果这一列没有放过,对角线和反对角线也没有放过{g[u][i]='Q'; //在当前的位置放上皇后col[i] = dg[n+u-i] = udg[u+i] = true; //记录当前位置已经被使用dfs(u+1); //全部处理好后进入下一层col[i] = dg[n+u-i] = udg[u+i] = false; //回溯的时候要恢复g[u][i]='.';  //回溯要把这个位置的皇后去掉}}    
}
输出的时候是按行输出
if( u == n ) //到最后一个位置的下一位(所有位置都填满了){for(int i=0;i<n;i++) puts(g[i]); //输出第i行的棋盘状态,g是二维数组,这样是按行输出puts("");return;}

 对于二维数组 g,可以通过 g[i] 访问到第 i 行的字符串,因为二维数组在内存中是按行存储的连续空间。

在 C++ 中,二维数组可以看作是一维数组的数组。对于 g 这样的二维数组,g[i] 表示的是第 i 个一维数组的起始地址,即第 i 行的地址。由于数组名就是该数组的首地址,因此可以直接使用 g[i] 来表示第 i 行。

其中
if(!col[i] && !dg[n+u-i] && !udg[u+i])

这个判断条件是检查在当前点g[u][i]上的竖列,正对角线和反对角线上是否有皇后(因为我们是一行一行的输入,然后按列枚举皇后在当前行的摆法,所以不用判断行上有没有其他皇后)。

dg和udg的下标可能较难理解,如果图中的点位置用(x,y)表示x行y列,那么这里的u对应行,i对应列,也就是(u,i)表示当前点的位置,这里画图可知道同一条反对角线上,u+i是一样的,而同一条正对角线上,u-i是一样的,但是因为这里用下标表示第几条正对角线,下标不能为负,所以我们加上一个n使下标为正数(加上之后不影响下标表达,比如原来正对角线的下标有-3,-1,2,7,我们加上一个n=4之后就变为1,3,6,11,实际上每个下标还是分开的能映射到对应的正对角线)

示例代码:
#include<iostream>
using namespace std;
const int N=20; //对角线是格子的两倍长
char g[N][N]; //记录棋盘状态信息
bool col[N],dg[N*2],udg[N*2]; //col列,dg记录正对角线的占用情况,udg记录负对角线的占用
int n;void dfs(int u) //u表示行,输出每一行皇后的位置
{if( u == n ) //到最后一个位置的下一位(所有位置都填满了){for(int i=0;i<n;i++) puts(g[i]); //输出第i行的棋盘状态,g是二维数组,这样是按行输出puts("");return;}for(int i=0;i<n;i++) //对于一行,枚举每一列的情况{//行是u,列是i//dg下标n-u+i,udg下标u+i,如果下标相同就说明是同一条对角线if(!col[i] && !dg[n+u-i] && !udg[u+i]) //如果这一列没有放过,对角线和反对角线也没有放过{g[u][i]='Q'; //在当前的位置放上皇后col[i] = dg[n+u-i] = udg[u+i] = true; //记录当前位置已经被使用dfs(u+1); //全部处理好后进入下一层col[i] = dg[n+u-i] = udg[u+i] = false; //回溯的时候要恢复g[u][i]='.';  //回溯要把这个位置的皇后去掉}}    
}
int main()
{cin>>n;for(int i=0;i<n;i++){for(int j=0;j<n;j++){g[i][j]='.';  //初始化,棋盘全部为'.'}}dfs(0); //从第0行开始看}
关于代码运行的流程:n=4的情况

注意:不仅是return有回溯到上一列的效果,当进入递归中,上一列的for循环也是可以让当前列回溯到上一列。 

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

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

相关文章

深入了解Java 8 新特性:Stream流的实践应用(一)

阅读建议 嗨&#xff0c;伙计&#xff01;刷到这篇文章咱们就是有缘人&#xff0c;在阅读这篇文章前我有一些建议&#xff1a; 本篇文章大概一万多字&#xff0c;预计阅读时间长需要10分钟&#xff08;不要害怕字数过多&#xff0c;其中有一大部分是示例代码&#xff0c;读起…

数据结构【DS】图的遍历

BFS 要点 需要一个辅助队列visited数组&#xff0c;防止重复访问 复杂度 时间复杂度&#xff1a;访问结点的时间访问所有的边的时间 广度优先生成树 邻接表存储的图的表示方式不唯一&#xff0c;生成树也不唯一 DFS 复杂度 时间复杂度&#xff1a;访问结点的时间访问所有…

万字解析设计模式之桥接模式、外观模式

一、桥接模式 1.1概述 桥接模式是一种结构型设计模式&#xff0c;它的作用是将抽象部分和实现部分分离开来&#xff0c;使它们能够独立地变化。这样&#xff0c;抽象部分和实现部分可以分别进行扩展&#xff0c;而不会相互影响。它是用组合关系代替继承关系来实现&#xff0c;…

全链路压测的步骤及重要性

全链路压测是一种系统性的性能测试方法&#xff0c;旨在模拟真实用户场景下的完整操作流程&#xff0c;全面评估软件系统在不同压力下的性能表现。这种测试方法对于保证应用程序的高可用性、稳定性和可扩展性至关重要。 1. 全链路压测概述 全链路压测是在模拟实际用户使用场景的…

什么是PyQt?

什么是Qt? Qt是一个著名的跨平台C图形用户界面应用程序开发框架。它由Qt公司开发,于1995年首次发布。Qt支持各种桌面,嵌入式和移动平台。 Qt的特点包括: 跨平台支持:Qt应用程序可以编译到多种平台运行,包括Windows,Mac,Linux,Android,iOS等。这大大简化了跨平台应用程序的开…

2019ICPC南京站

A A Hard Problem 题意&#xff1a;给定一个正整数 n &#xff0c;你需要找出最小整数 k&#xff0c;满足&#xff1a;从{1,2,⋯,n}中任意选择长度为k的子集&#xff0c;存在两个不同的整数 u,v∈T, 且 u 是 v 的因数。 思路&#xff1a;打表找规律 #include <bits/std…

JSP:Tag文件的使用

需求&#xff1a;多个JSP页面可能需要使用一些相同的信息 例如:导航栏、标题等。 目标&#xff1a;提高这些相同信息的代码的复用性。 方法&#xff1a;将这些相同的元素形成一种特殊的文件&#xff0c;以便所有页面都可以使用&#xff0c;即&#xff1a;Tag文件 1、Tag对…

MySQL数据库入门到大牛_基础_10_创建和管理表(创建和管理数据库;创建表;修改表;重命名表;删除表;清空表,内容扩展)

前面我们完成了查询结构的介绍&#xff0c;本章介绍DDL和DCL中的COMMIT和ROLL BACK。 文章目录 1. 基础知识1.1 一条数据存储的过程1.2 标识符命名规则1.3 MySQL中的数据类型 2. 创建和管理数据库2.1 创建数据库2.2 使用数据库2.3 修改数据库2.4 删除数据库 3. 创建表3.1 创建…

猫罐头哪个牌子好吃?精选5款好评率高的猫罐头推荐!

很多新手养猫的姐妹们都会为选罐头感到焦虑&#xff01;因为每种猫罐头都有优缺点&#xff0c;每只猫咪的胃口也都不同&#xff0c;所以只有综合考虑选择适合自家猫咪的猫罐头的才是最好的。所以姐妹们在选罐头之前可以先做好功课&#xff0c;了解一下怎么选好的猫罐头。 作为开…

Jmeter监听器

Jmeter监听器 一、监听器介绍二、监听器的类型三、监听器详解3.1 察看结果树3.2 Summary Report3.3 聚合报告3.4 后端监听器3.5 Aggregate Graph3.6 Comparison Assertion Visualizer&#xff08;比较断言可视化器&#xff09;3.7 JSR223 Listener3.8 Response Time Graph3.9 S…

欧科云链研究院:从香港SFC最新文件看链上交易合规必备之选

出品&#xff5c;欧科云链研究院 作者&#xff5c;Hedy Bi 近日&#xff0c;香港证监会在其官网发布“致持牌法团、获证监会发牌的虚拟资产服务提供者及有联系实体的通函 - 打击洗钱&#xff0f;恐怖分子资金筹集经更新的《打击洗钱&#xff0f;恐怖分子资金筹集的自我评估查…

CICD 持续集成与持续交付(2)

目录 gitlab 部署 jenkins 部署 配置 实时触发 自动化构建docker镜像 通过ssh插件交付任务 添加jenkins节点 RBAC pipeline jenkins结合ansible参数化构建 安装ansible 新建gitlab项目 jenkins新建项目playbook gitlab 部署 虚拟机最小需求&#xff1a;4G内存 4核cpu 下载&…

【智能优化算法】从蚁群到动物园

目录 引言蚁群优化算法&#xff08;ACO&#xff09;ACO 机理ACO 模型描述ACO 移动策略 粒子群优化算法&#xff08;PSO&#xff09;PSO 机理PSO 模型描述 萤火虫群优化算法&#xff08;GSO&#xff09;GSO 机理GSO 模型描述 群智能优化算法 引言 21世纪&#xff0c;人类社会已经…

ElementUI用el-table实现表格内嵌套表格

文章目录 一、效果图二、使用场景三、所用组件元素&#xff08;Elementui&#xff09;四、代码部分 一、效果图 二、使用场景 &#x1f6c0;el-form 表单内嵌套el-table表格 &#x1f6c0;el-table 表格内又嵌套el-table表格 三、所用组件元素&#xff08;Elementui&#xff…

Kubeadm部署Kubernetes Containerd集群

文章目录 概述一、硬件系统二、基础配置设置主机名配置主机名与IP地址解析关闭防火墙与selinux时间同步(ntp)升级系统内核配置内核转发及网桥过滤*安装ipset及ipvsadm关闭SWAP分区 三、Containerd准备Containerd获取下载解压Containerd配置文件生成并修改Containerd启动及开机自…

5年经验之谈 —— 性能测试如何定位分析性能瓶颈?

你好&#xff0c;我是小牛&#xff0c;目前在一家准一线互联网大厂做测试开发工程师。 对于一般公司普通测试工程师来说&#xff0c;可能性能测试做的并不是很复杂&#xff0c;可能只是编写下脚本&#xff0c;做个压测&#xff0c;然后输出报告结果&#xff0c;瓶颈分析和调优…

【Hello Go】Go语言复合类型

复合类型 分类指针基本操作new函数指针作为函数的参数 数组概述操作数据数组初始化数组比较在函数之间传递数组 slice概述切片的创建和初始化切片操作切片和底层数组关系内建函数appendcopy 切片作为函数传参 map概述创建和初始化常用操作赋值遍历 删除map作函数参数 结构体结构…

Python (十三) 输出

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…

基于Python+TensorFlow+Django的交通标志识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 随着交通网络的不断扩展和智能交通系统的发展&#xff0c;交通标志的自动识别变得愈发重要。本项目旨在利用Python编…

利用SVD对图像进行压缩

利用SVD对图像进行压缩 使用SVD能够对数据进行降维&#xff0c;对图像进行SVD&#xff0c;降维之后然后重构数据&#xff0c;还原后的图像就是压缩后的图像。 SVD SVD进行图像压缩所依据的数学原理就是矩阵的近似表示&#xff1a; A m n ≈ U m k ∑ k k V k n T A_{m\…