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

问题描述:

有一个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.hqwc.cn/news/681817.html

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

相关文章

什么是虚拟货币?

随着科技的进步&#xff0c;虚拟货币逐渐进入公众视野&#xff0c;其影响深远且复杂。本文将从专业角度分析虚拟货币的发展现状、未来趋势&#xff0c;以及面临的挑战&#xff0c;并尝试提出一些思考。 一、虚拟货币的定义与现状 虚拟货币是一种基于区块链技术的数字资产&…

Golang入门教程(非常详细)从零基础入门到精通,看完这一篇就够了

文章目录 一、golang 简介 1. go 语言特点2. go 语言应用领域3. 使用 go 语言的公司有哪些 二、安装 golang 1. golang 下载安装2. 配置环境变量 三、golang 开发工具 1. 安装 VSCode2. 下载所需插件 四、第一个 golang 应用 1. main 包的含义2. 示例 一、golang 简介 Go 是一…

Pytorch入门—Tensors张量的学习

Tensors张量的学习 张量是一种特殊的数据结构&#xff0c;与数组和矩阵非常相似。在PyTorch中&#xff0c;我们使用张量来编码模型的输入和输出&#xff0c;以及模型的参数。 张量类似于NumPy的ndarrays&#xff0c;只是张量可以在GPU或其他硬件加速器上运行。事实上&#xf…

音转文工具,9.8k star! 【送源码】

我们经常会遇到将音频转为文字的情况&#xff0c;比如在开会时录音的会议纪要、上课时录下的老师讲课内容。虽然网上也有一些在线的工具可以将音频转为文字&#xff0c;但是考虑到数据安全和费用问题&#xff0c;使用起来也不是很方便。 今天了不起给大家介绍一款开源工具——…

#友元函数与友元类

目录 1.概念 2.友元函数 3.友元类 1.概念 友元提供了一种突破封装的方式&#xff0c;有时提供了便利。但是友元会增加耦合度&#xff0c;破坏了封装&#xff0c;所以友元不宜多 用。 友元分为&#xff1a;友元函数和友元类 2.友元函数 友元函数可以直接访问类的私有成员&a…

「MDN web 入门」学习笔记

目录 写在前面 1. MDN 简介 1.1 MDN 的主要特点 1.2 MDN 的主要功能 1.3 MDN 网页开发的指南 2. 安装基础软件 2.1 专业人士工具 2.2 初学者基本工具 3. 设计网站外观 3.1 计划 3.2 绘制草图 3.3 选定素材 3.4 文本 3.5 主题颜色 3.6 图像 3.7 字体 4. 处理文…

六西格玛项目的核心要素:理论学习、实践应用与项目经验

许多朋友担心&#xff0c;没有项目经验是否就意味着无法考取六西格玛证书。针对这一疑问&#xff0c;张驰咨询为大家详细解答。 首先&#xff0c;需要明确的是&#xff0c;六西格玛项目不仅仅是一种管理工具或方法&#xff0c;更是一种追求卓越、持续改进的思维方式。它强调通…

5.07 Pneumonia Detection in Chest X-Rays using Neural Networks

肺炎诊断是一个耗时的过程&#xff0c;需要高技能的专业人员分析胸部X光片chest X-ray (CXR)&#xff0c;并通过临床病史、生命体征和实验室检查确认诊断。 它可以帮助医生确定肺部感染的程度和位置。呼吸道疾病在 X 光片上表现为一处膨胀的不透明区域。然而&#xff0c;由于不…

科技云报道:从亚运到奥运,大型国际赛事共赴“云端”

科技云报道原创。 “广播电视转播技术拯救了奥运会”前奥委会主席萨马兰奇这句话广为流传。 奥运会、世界杯、亚运会这样的全球大型体育赛事不仅是体育竞技的盛宴&#xff0c;也是商业盛宴&#xff0c;还是技术与人文的融合秀。随着科技的进步&#xff0c;技术在体育赛事中扮…

2.外卖点餐系统(Java项目 springboot)

目录 0.系统的受众说明 1.系统功能设计 2.系统结构设计 3.数据库设计 3.1实体ER图 3.2数据表 4.系统实现 4.1用户功能模块 4.2管理员功能模块 4.3商家功能模块 4.4用户前台功能模块 4.5骑手功能模块 5.相关说明 新鲜运行起来的项目&#xff1a;如需要源码数据库…

树形数据结构---堆

1.概念 什么是堆&#xff1f;堆和树的区别是什么&#xff1f;它的应用场景有哪些&#xff1f; 堆&#xff08;Heap&#xff09;是一种基于树形结构的数据结构&#xff0c;它是一种特殊的完全二叉树。堆的特点是每个节点都满足堆的性质&#xff0c;即父节点的键值总是大于或等…

8.删除有序数组中的重复项 II

文章目录 题目简介题目解答解法一&#xff1a;双指针&#xff08;快慢指针&#xff09;代码&#xff1a;复杂度分析&#xff1a; 题目链接 大家好&#xff0c;我是晓星航。今天为大家带来的是 删除有序数组中的重复项 II 相关的讲解&#xff01;&#x1f600; 题目简介 题目解…