经典回溯算法之N皇后问题

news2025/1/9 1:46:23

问题描述:

有一个N*N的棋盘,需要将N个皇后放在棋盘上,保证棋盘的每一行每一列每一左斜列每一右斜列都最多只能有一个皇后。

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

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

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

像下图这样的放置即满足条件:

这是一组答案的样式:

思路解析:

可以很明显的看到,这是一个对列进行排列型枚举问题。如果我们暴力搜索每一种列排列,再对其验证是否满足条件,当有6个皇后就有6!==720种方案,时间复杂度很高O(n!*n)。

很显然暴力枚举是不切实际的做法,有时候我们放置i个皇后(i<n)发现冲突时就已经不满足条件了,这部分可以进行剪枝。

总体思路:

使用回溯的思想,依次在1-n行放入皇后,保证放入第i行的皇后不会和前i-1个皇后发生冲突,当我们放到第n+1个时此时n个皇后已经放置完毕,并且保证前n个不冲突即找到答案。

当放到第i行时(i<=n)发现不管放在该行的哪一列都会产生冲突时,此时说明当前方案不合适,回溯到i-1行重新选择皇后进行放置。

关于如何判断是否产生冲突,使用状态码表示哪些行哪些列哪些斜列可以放置,每放置一个皇后将它能攻击的范围给他置为0。

关于状态压缩:使用二进制的表示方式,0代表该行/列/斜列不能放置了,1则可以放置

直接给出详细代码及其解析好吧!!!

代码及注释详解:

#include<iostream>
#include<unordered_map>
using namespace std;


int arr[15];


//掩码到实际列的映射
unordered_map<int, int>umap;

int k = 3;
void print_one_result(int n) {
	if (k) {
		for (int i = 1; i <= n; i++) {
			if (i != 1)cout << " " << arr[i];
			else cout << arr[i];
		}
		cout << endl;
		k--;
	}

}
//a 枚举到第几行
//b 哪些列可以选
//c 哪些做些列可以选
//d 哪些右斜列可以选
//e 几个皇后
int dfs(int a, int b, int c, int d, int e) {
	//所有皇后放置完毕
	if (a > e) {
		print_one_result(e);
		return 1;
	}
	int ans = 0;
	//j代表第几列
	for (int t = b, j; t; t -= t & (-t)) {
		j = umap[t & (-t)];
		arr[a] = j;

		//说明该放置位置(a,j)不产生冲突
		if ((c & (1 << a + j - 1)) && (d & (1 << a - j + e))) {
			//递归到下一行放置
			//并且禁用该范围
			ans += dfs(a + 1, b ^ (t & -t), c ^ (1 << a + j - 1), d ^ (1 << a - j + e), e);
		}
	}
	return ans;


}

void Nqueen() {
	int n;
	cin >> n;

	//掩码到实际表示的映射 :比如 0100表示第2(行/列/斜列)
	for (int i = 1; i <= n; i++) {
		umap[1 << i] = i;
	}

	//刚开始每一列都没有放置  假设n==6 
	//(1 << (n + 1)) - 2 代表 01111110 有6列可以放置
	//0111111111110 代表斜列
	cout << dfs(1, (1 << (n + 1)) - 2, (1 << n * 2) - 2, (1 << n * 2) - 2, n);


}
int main() {
	Nqueen();
	return 0;
}

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

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

相关文章

智慧粮库/粮仓视频监管系统:AI视频智能监测保障储粮安全

智慧粮库视频监管系统是一种基于物联网、AI技术和视频监控技术的先进管理系统&#xff0c;主要用于对粮食储存环境进行实时监测、数据分析和预警。TSINGSEE青犀智慧粮库/粮仓视频智能管理系统方案通过部署多区域温、湿度、空气成分等多类传感器以及视频监控等设施&#xff0c;对…

猎头告诉你正确的“离职流程”

往期热门文章&#xff1a; 1&#xff0c;史上最全猎头技能资料&#xff0c;独家最新放送 2&#xff0c;互联网大厂java面试题知识库&#xff08;100万字&#xff09; 3&#xff0c;一线互联网大数据面试题知识库&#xff08;100万字&#xff09; 4&#xff0c;中国猎头公司排行…

Python数据分析的数据导入和导出

数据分析的数据的导入和导出 前言一、导入数据导入Excel表格数据read_excel示例 导入CSV格式数据read_csv&#xff08;&#xff09;示例 导入JSON格式数据JSON简介pandas导入JSON数据read_json&#xff08;&#xff09; 导入txt文件read_table示例 导入&#xff08;爬取&#x…

5月9日不同路径+不同路径Ⅱ

62.不同路径 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径&#…

<网络安全>《76 概念讲解<第十课 物联网常用协议-网络层协议>》

协议简称全称名称内容说明IPv4互联网通信协议第四版IPv4是互联网的核心IPv6互联网协议第6版TCPTransmission Control Protocol传输控制协议TCP旨在适应支持多网络应用的分层协议层次结构。连接到不同但互连的计算机通信网络的主计算机中的成对进程之间依靠TCP提供可靠的通信服务…

【递归、回溯和剪枝】二叉树中的深搜

⼆叉树中的深搜深度优先遍历&#xff08;DFS&#xff0c;全称为 Depth First Traversal&#xff09;&#xff0c;是我们树或者图这样的数据结构中常⽤的⼀种遍历算法。这个算法会尽可能深的搜索树或者图的分⽀&#xff0c;直到⼀条路径上的所有节点都被遍历完毕&#xff0c;然后…

【AI大模型】AI大模型热门关键词解析与核心概念入门

&#x1f680; 作者 &#xff1a;“大数据小禅” &#x1f680; 文章简介 &#xff1a;本专栏后续将持续更新大模型相关文章&#xff0c;从开发到微调到应用&#xff0c;需要下载好的模型包可私。 &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 目…

微电子领域常用材料简介(三)氮化镓

微电子领域常用材料简介&#xff08;三&#xff09;氮化镓 氮化镓&#xff08;GaN&#xff09;是一种具有重要战略意义的第三代半导体材料&#xff0c;因其独特的物理和化学性质&#xff0c;在多个领域展现出广泛的应用潜力。 基本特性 宽禁带&#xff1a;氮化镓具有宽带隙&a…

崇贸烧录器支持PUYA普冉半导体的32位微控制器PY32F403R1DT6

芯片烧录行业领导者-崇贸技术近日发布最新的烧录软件更新及新增支持的芯片型号列表&#xff0c;其中PUYA普冉半导体的32位微控制器PY32F403R1DT6已经被崇贸的通用烧录平台AP8000所支持。 PY32F403R1DT6微控制器是基于ArmCortexM4核的32位通用微控制器产品。内置的FPU和DSP功能…

C语言 变量的作用域

今天 我们来说变量的作用域和存储类型 每种事物 都有自己作用的范围限制 例如 汽车只能在路上跑 轮船只能在海洋 飞机只能通行于天空 函数的参数 也只有在函数被调用过程中分配内存资源 函数执行结束 空间也会被立即释放 这也说明了 行参变量只有在函数内才有效 离开了该函数 …

程序员的实用神器,16款程序员生产力工具推荐

前言 在软件开发的海洋中&#xff0c;程序员的实用神器如同航海中的指南针&#xff0c;帮助他们导航、加速开发、优化代码质量&#xff0c;并最终抵达成功的彼岸。这些工具覆盖了从代码编写、版本控制到测试和部署的各个环节。 一、程序员开发工具 Intellij IDEA IntelliJ I…

【Linux网络编程】HTTPS协议

【Linux网络编程】HTTPS协议 目录 【Linux网络编程】HTTPS协议HTTPS介绍加密常见的加密方式HTTPS的工作过程探究&#xff08;重点&#xff09;常见问题完整流程总结 作者&#xff1a;爱写代码的刚子 时间&#xff1a;2024.5.9 前言&#xff1a;本篇博客将会介绍HTTPS协议 HTTPS…

Linux-笔记 uboot修改设备树

1. FDT介绍 扁平设备树&#xff08;Flattened Device Tree&#xff0c;FDT&#xff09;&#xff0c;也叫平坦设备树&#xff0c;是设备树的一种二进制表示形式&#xff0c;提高了在嵌入式系统中的传输和解析效率&#xff1b; 2. 在U-Boot中使用FDT 2.1. 进入U-Boot 开发板上…

企业级通用业务 Header 处理方案

目录 01: 处理 PC 端基础架构 02: 通用组件&#xff1a;search 搜索框能力分析 03: 通用组件&#xff1a;search 搜索框样式处理 04: 通用组件&#xff1a;Button 按钮能力分析 05: 通用组件&#xff1a;Button 按钮功能实现 06: 通用组件&#xff1a;完善 search 基本…

【漏洞复现】GB28181摄像头管理平台api接口处存在未授权漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

【北京迅为】《iTOP-3588开发板nfstftp烧写手册》

RK3588是一款低功耗、高性能的处理器&#xff0c;适用于基于arm的PC和Edge计算设备、个人移动互联网设备等数字多媒体应用&#xff0c;RK3588支持8K视频编解码&#xff0c;内置GPU可以完全兼容OpenGLES 1.1、2.0和3.2。RK3588引入了新一代完全基于硬件的最大4800万像素ISP&…

力扣HOT100 - 4. 寻找两个正序数组的中位数

解题思路&#xff1a; 两个数组合并&#xff0c;然后根据奇偶返回中位数。 class Solution {public double findMedianSortedArrays(int[] nums1, int[] nums2) {int m nums1.length;int n nums2.length;int[] nums new int[m n];if (m 0) {if (n % 2 0) return (nums2…

若依集成mybatis-plus 超详细教程(亲测可用)

文章目录 简介步骤第一步第二步第三步第四步第五步第六步 使用QueryWrapperservice层impl 实现接口类层Mapper层 简介 话不多说 直接跟着下面的教程操作&#xff0c;如果有报错私信我&#xff0c;或者通过博文下面的微信名片加我微信&#xff0c;免费解答哦&#xff01; 步骤 …

代码随想录刷题随记31-贪心5

代码随想录刷题随记31-贪心5 435. 无重叠区间 leetcode链接 按照右边界排序&#xff0c;从左向右记录非交叉区间的个数。 此时问题就是要求非交叉区间的最大个数。 这里记录非交叉区间的个数还是有技巧的&#xff0c;如图&#xff1a; 左边界排序可不可以呢&#xff1f; 也是…