N皇后问题详解:回溯算法的应用与实践(dfs)

在这里插入图片描述

目录

  • 一.问题描述
    • 二.思路分析
      • 1.DFS
      • 三.代码实现与解析
      • 1.分析
      • 2.完整代码

一.问题描述

在这里插入图片描述
题目如上图所示,在一个n*n的国际象棋棋盘上怎么摆放能使得皇后互相攻击不到(也就是在任意一列、一行、一条对角线上都不存在两个皇后

二.思路分析

1.DFS

想要解决这个问题,我们可以使用dfs也就是深度优先遍历,深度优先搜索的步骤为先递归到底再回溯上来,顾名思义,dfs是以深度为目标,一条路走到底,直到达到无路可走时,退回到上一步的状态,走其他路回溯上来。
这题我们就可以定义数组当做棋盘,遍历所有位置判断是否可以放置皇后(需要满足任意一列、一行、一条对角线上都不存在两个皇后),在遍历的过程中需要考虑剪枝的情况,减少解题时间复杂度。

三.代码实现与解析

1.分析

首先我们创建完数组模拟棋盘后,先要依据题意,将数组初始化为.

#include <iostream>
const int N = 20;
using namespace std;
char ret[N][N];

bool col[N], dg[N], udg[N];//标记列、对角线上是否已经有皇后

int n = 0;

void dfs(int u);

int main()
{
	cin >> n;
	for (int i = 0; i < n; i++)
		for (int m = 0; m < n; m++)
			ret[i][m] = '.';

	dfs(0);//dfs算法函数
	return 0;
}

紧接着就是dfs函数代码的实现逻辑:

void dfs(int u)
{
	if (u == n)
	{
		for (int i = 0; i < n; i++)
		{
			cout << ret[i] << endl;;
		}
		cout<< endl;
		return;
	}

	for (int i = 0; i < n; i++)
	{
		if (!col[i] && !dg[u + i] && !udg[n + i - u])
		{
			ret[u][i] = 'Q';
			col[i] = dg[u + i] = udg[n + i - u] = true;
			dfs(u + 1);
			ret[u][i] = '.';
			col[i] = dg[u + i] = udg[n + i - u] = false;
		}
	}
}

需要重点理解的在for循环中i代表的是列数(遍历的是列),u代表的是层数,if判断当行、对角线均暂无皇后时,则可以在此放置皇后,并标识为已经放置,此时这一层的放置就结束了,所以接着就要递归下一层,之后就会分为两种情况:
1.递归到最后一层成功打印了这次的方案。接着就会向上回溯

ret[u][i] = '.';
col[i] = dg[u + i] = udg[n + i - u] = false;

执行恢复逻辑。
2.在后续层数遍历放置时,出现了不合法的情况(列数到达阈值依旧没有放置),此时就会剪枝,也是会回溯到上图代码进行恢复。

2.完整代码

#include <iostream>
const int N = 20;
using namespace std;
char ret[N][N];

bool col[N], dg[N], udg[N];

int n = 0;

void dfs(int u);

int main()
{
	cin >> n;
	for (int i = 0; i < n; i++)
		for (int m = 0; m < n; m++)
			ret[i][m] = '.';

	dfs(0);
	return 0;
}
void dfs(int u)
{
	if (u == n)
	{
		for (int i = 0; i < n; i++)
		{
			cout << ret[i] << endl;;
		}
		cout<< endl;
		return;
	}

	for (int i = 0; i < n; i++)
	{
		if (!col[i] && !dg[u + i] && !udg[n + i - u])
		{
			ret[u][i] = 'Q';
			col[i] = dg[u + i] = udg[n + i - u] = true;
			dfs(u + 1);
			ret[u][i] = '.';
			col[i] = dg[u + i] = udg[n + i - u] = false;
		}
	}
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C/C++内存管理及内存泄漏详解

目录 C/C内存分布 C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free C内存管理方式 new/delete操作内置类型 new和delete操作自定义类型 operator new与operator delete函数 new和delete的实现原理 内置类型 自定义类型 内存泄漏 概念 内存泄漏分类 ⭐…

虚拟化介绍

虚拟化理论介绍 什么是虚拟化: 虚拟化&#xff08;Virtualization&#xff09;技术最早出现在 20 世纪 60 年代的 IBM 大型机系统。 在70年代的 System 370 系列中逐渐流行起来&#xff0c;这些机器通过一种叫虚拟机监控器&#xff08;Virtual Machine Monitor&#xff0c;V…

网络仿真(一)

网络仿真的意义 在网络规划和设计、网络设备研发、网络协议开发中&#xff0c;需要一种手段来反映和预测网络的性能 网络仿真可以提高网络规划设计的可靠性和准确性&#xff0c;明显降低网络投资风险&#xff0c;减少不必要的浪费 Ns-2 is a discrete event simulator Sched…

Page Object模式:为什么它是Web自动化测试的必备工具

为 UI 页面写测试用例时&#xff08;比如 web 页面&#xff0c;移动端页面&#xff09;&#xff0c;测试用例会存在大量元素和操作细节。当 UI 变化时&#xff0c;测试用例也要跟着变化&#xff0c; PageObject 很好的解决了这个问题。 使用 UI 自动化测试工具时&#xff08;包…

LabVIEW石油钻机提升系统数字孪生技术

LabVIEW石油钻机提升系统数字孪生技术 随着数字化、信息化、智能化的发展&#xff0c;石油钻采过程中的石油钻机数字化技术提升成为了提高钻井效率、降低生产成本的重要途径。基于中石油云平台提供的数据&#xff0c;采用数字孪生技术&#xff0c;对石油钻机提升系统进行数字化…

配置之道:深入研究Netty中的Option选项

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 配置之道&#xff1a;深入研究Netty中的Option选项 前言Option的基础概念ChannelOption与Bootstrap Option常见的ChannelOption类型ChannelConfig的使用Option的生命周期不同传输协议的Option 前言 在…

云时代【7】—— 存储卷

云时代【7】—— 存储卷 四、Docker&#xff08;四&#xff09;存储卷1. 存储卷&#xff08;1&#xff09;定义&#xff08;2&#xff09;分类 2. 相关指令&#xff08;1&#xff09;管理卷 VolumeA. 创建方式方式一&#xff1a;docker volume方式二&#xff1a;docker run -v …

美国教授查理曼说中国为何强大?中国人都不知道的民族特性

Title: 中国强大的秘密&#xff1a;查理曼教授的视角 在世界历史的长河中&#xff0c;中华民族以其辉煌灿烂的文化和举世瞩目的成就&#xff0c;书写了一篇篇传奇篇章。然而&#xff0c;对于中国人为什么能够取得如此卓越的成就&#xff0c;许多人却并不清楚。近日&#xff0c…

Linux搭建SFTP服务器

案例&#xff1a;搭建SFTP服务器 SFTP&#xff08;SSH文件传输协议&#xff09; SFTP&#xff08;SSH文件传输协议&#xff09;是一种安全的文件传输协议&#xff0c;用于在计算机之间传输文件。它基于SSH&#xff08;安全外壳协议&#xff09;的子系统&#xff0c;提供了加密的…

sqlserver保存微信Emoji表情

首先将数据库字段&#xff0c;设置类型为 nvarchar(200)一个emoji表情&#xff0c;占4字节就可以了&#xff0c;web前端展示不用改任何东西&#xff0c;直接提交数据保存&#xff1b;回显也会没有问题&#xff0c;C#代码不用做任何处理&#xff1b; 不哭不闹要睡觉&#x1f31…

若依框架使用mars3d的环境配置,地球构建

因项目需要&#xff0c;原本使用过的cesium依赖&#xff0c;现在想使用火星科技mars3d的一些功能&#xff0c;所以需要引入mars3d依赖&#xff0c;整个过程非常的坎坷&#xff0c;以至于我都不知道到底是哪些部分是标准的。。。先把我认为对的记录一下&#xff1a; 1.vue.conf…

【Java】SpringAOP —— AOP是什么? 代码实现了SpringAOP

文章目录 一、AOP是什么二、AOP的组成三、SpringAOP四、实现SpringAOP1.添加AOP框架支持2.定义切面切点3.定义相关通知 总结 一、AOP是什么 AOP&#xff08;Aspect Oriented Programming&#xff09;&#xff1a;面向切面编程&#xff0c;它是⼀种思想&#xff0c;它是对某一类…

JVM 第四部分—垃圾回收相关概念 2

System.gc() 在默认情况下&#xff0c;通过System.gc()或者Runtime.getRuntime().gc()的调用&#xff0c;会显式触发Full GC&#xff0c;同时对老年代和新生代进行回收&#xff0c;尝试释放被丢弃对象占用的内存 然而System.gc()调用附带一个免责声明&#xff0c;无法保证对垃…

基于Camunda实现bpmn 2.0各种类型的任务

基于Camunda实现bpmn中各种类型任务 ​ Camunda Modeler -为流程设置器&#xff08;建模工具&#xff09;&#xff0c;用来构建我们的流程模型。Camunda Modeler流程绘图工具&#xff0c;支持三种协议类型流程文件分别为&#xff1a;BPMN、DMN、Form。 ​ Camunda Modeler下载…

【Python】进阶学习:pandas--isin()用法详解

【Python】进阶学习&#xff1a;pandas–isin()用法详解 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448; 希望得到您的订阅…

【java】20:枚举

枚举的二种实现方式 1) 自定义类实现枚举 2) 使用 enum 关键字实现枚举 自定义实现枚举&#xff1a; 1.不需要提供setXxx方法&#xff0c;因为枚举对象值通常为只读. 2.对枚举对象/属性使用final static共同修饰&#xff0c;实现底层优化. 3.枚举对象名通常使用全部大写&…

电子电气架构——汽车以太网诊断路由汇总

电子电气架构——汽车以太网诊断路由汇总 我是穿拖鞋的汉子,魔都中坚持长期主义的工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 人们会在生活中不断攻击你。他们的主要武器是向你灌输对自己的怀疑:你的价值、你的能力、你的潜力。他们往往会将…

江科大stm32学习笔记——【4-1】OLED

一.原理 1.调试方式 串口调试&#xff1a;通过串口通信&#xff0c;将调试信息发送到电脑端&#xff0c;电脑使用串口助手显示调试信息。 显示屏调试&#xff1a;直接将显示屏连接到单片机&#xff0c;将调试信息打印在显示屏上。 Keil调试模式&#xff1a;借助Keil软件的调…

深入sizeof与strlen

一、sizeof与strlen的对比 sizeofstrlensizeof是单目操作符strlen是库函数&#xff0c;使用需要包含头文件string.hsizeof计算操作数所占用的内存&#xff0c;单位是字节strlen是求字符串长度&#xff0c;统计的是\0之前字符的个数不关注内存中存放什么数据 关注内存总是否有\0…

关于 HTTP 协议,你了解多少

HTTP协议 FastAPI 是建立在 HTTP 协议之上&#xff0c;所以为了更好的掌握 FastAPI。我们需要先简单的了解一下 HTTP协议 简介 HTTP&#xff08;Hypertext Transfer Protocol&#xff09;遵循经典的客户端-服务器模型&#xff0c;客户端打开连接以发出请求&#xff0c;然后等…