当前位置: 首页 > news >正文

八皇后问题

1、问题描述

在棋盘上放置 8 个皇后,使得它们互不攻击,此时每个皇后的攻击范围为同行同列和同对角线,要求找出所有解,如下图所示。

在这里插入图片描述
左图为皇后的攻击范围,右图为一个可行解。

2、分析

最简单的思路是把问题转化为 “从 64 个格子中选一个子集”,使得 “子集中恰好 8 个格子,且任意两个选出的格子都不在同一行、同一列或同一个对角线上”。这正是子集枚举问题。然而,64个格子的子集有264 个,太大了,这并不是一个很好的模型。

第二个思路是把问题转化为 “从 64 个格子中选 8 个格子”,这是组合生成问题。根据组合数学,有 C 64 8 = 4.426 × 1 0 9 C_{64}^8 = 4.426 \times 10^9 C648=4.426×109 种方案,比第一种方案优秀,但仍然不够好。

经过思考,不难发现以下事实:恰好每行每列各放置一个皇后。如果用 C[x] 表示第 x 行皇后的列编号,则问题变成了全排列生成问题。 而 0 ~ 7 的排列一共只有 8! = 40320个,枚举量不会超过它。

提示:在编写递归枚举程序之前,需要深入分析问题,对模型精雕细琢。一般还应对解答树的结点数有一个粗略的估计,作为评价模型的重要依据,如下图所示。

在这里插入图片描述
图中给出四皇后问题的完整解答树。它只有 17 个结点,比 4! = 24 小。之所以会这样,是因为有些结点无法继续扩展。如在 (0,2,*,*) 中,第2行无论将皇后放到哪里,都会和第 0 行和第1行中已放好的皇后发生冲突,其他还未放置的皇后更是如此。

在这种情况下,递归函数将不再递归调用它自身,而是返回上一层调用,这种现象称为回溯(backtracking)

提示:当把问题分成若干步骤并递归求解时,如果当前步骤没有合法的选择,则函数将返回上一级递归调用,这种现象称为回溯。正是因为这个原因,递归枚举算法常被称为回溯法,应用十分普遍。

下面的程序简洁地求解了八皇后问题。在主程序中读入 n n n,并为 t o t tot tot 清零,然后调用 search(0),即可得到解的个数 tot

void search(int cur) {if (cur == n) //递归边界,只要走到了这里,所有皇后必然不冲突tot++; else {for (int i = 0; i < n; i++) {int ok = 1;C[cur] = i; //尝试把第cur行的皇后放到第i列for (int j = 0; j < cur; j++) { //检查是否和前面的皇后冲突if (C[cur] == C[j] || cur - C[cur] == j - C[j] || cur + C[cur] == j + C[j]) {ok = 0;break;}}if (ok) search(cur + 1); //如果合法,继续递归}}
}

注意:既然是逐行放置的,则皇后肯定不会横向攻击,因此只需检查是否纵向和斜向攻击即可。条件 “cur - C[cur] == j - C[j] || cur + C[cur] == j + C[j]” 用来判断皇后 (cur, C[cur])(j, C[j]) 是否在同一条对角线上。其原理可用下图来说明。

在这里插入图片描述
结点数似乎很难进一步减少了,但程序效率可以继续提高:利用二维数组 vis[2][] 直接判断当前尝试的皇后所在的列和两个对角线是否已有其他皇后。注意到主对角线标识 y − x y-x yx 可能为负,存取时要加上 n n n

void search(int cur) {if(cur == n) tot++;else {for(int i = 0; i < n; i++) {if(!vis[0][i] && !vis[1][cur+i] && !vis[2][cur-i+n]) { //利用二维数组直接判断C[cur] = i; //如果不用打印解,整个C数组都可以省略vis[0][i] = vis[1][cur+i] = vis[2][cur-i+n] = 1; //修改全局变量search(cur+1);vis[0][i] = vis[1][cur+i] = vis[2][cur-i+n] = 0; //切记!一定要改回来}}}
}

上面程序有个极其关键的地方:vis 数组的使用。vis数组的确切含义:表示已经放置的皇后占据了哪些列、主对角线和副对角线。将来放置的皇后不应该修改这些值——至少“看上去没有修改”。一般地,如果在回溯法中修改了辅助的全局变量,则一定要及时把它们恢复原状(除非故意保留所做修改)。 另外,在调用之前一定要把 vis 数组清空。

提示:如果在回溯法中使用了辅助的全局变量,则一定要及时把它们恢复原状。特别地,若函数有多个出口,则需在每个出口处恢复被修改的值。

3、完整代码

n皇后问题:生成-测试法

#include<cstdio>
using namespace std;int C[50], tot = 0, n = 8, nc = 0;void search(int cur) {int i, j;nc++;if(cur == n) {for(i = 0; i < n; i++)for(j = i+1; j < n; j++)if(C[i] == C[j] || i-C[i] == j-C[j] || i+C[i] == j+C[j]) return;tot++;} else {for(i = 0; i < n; i++) {C[cur] = i;search(cur+1);}}
}int main() {scanf("%d", &n);search(0);printf("%d\n", tot);printf("%d\n", nc);return 0;
}

n皇后问题:普通回溯法

#include<cstdio>
using namespace std;int C[50], tot = 0, n = 8, nc = 0;void search(int cur) {int i, j;nc++;if(cur == n) {tot++;} else { for(i = 0; i < n; i++) {int ok = 1;C[cur] = i;for(j = 0; j < cur; j++) {if(C[cur] == C[j] || cur-C[cur] == j-C[j] || cur+C[cur] == j+C[j]) {ok = 0;break;}}if(ok) search(cur+1);}}
}int main() {scanf("%d", &n);search(0);printf("%d\n", tot);printf("%d\n", nc);return 0;
}

n皇后问题:优化的回溯法

#include<cstdio>
#include<cstring>
using namespace std;int C[50], vis[3][50], tot = 0, n = 8, nc = 0;void search(int cur) {int i, j;nc++;if(cur == n) {tot++;} else for(i = 0; i < n; i++) {if(!vis[0][i] && !vis[1][cur+i] && !vis[2][cur-i+n]) {C[cur] = i;vis[0][i] = vis[1][cur+i] = vis[2][cur-i+n] = 1;search(cur+1);vis[0][i] = vis[1][cur+i] = vis[2][cur-i+n] = 0;}}
}int main() {scanf("%d", &n);memset(vis, 0, sizeof(vis));search(0);printf("%d\n", tot);printf("%d\n", nc);return 0;
}

相关文章:

八皇后问题

1、问题描述 在棋盘上放置 8 个皇后&#xff0c;使得它们互不攻击&#xff0c;此时每个皇后的攻击范围为同行同列和同对角线&#xff0c;要求找出所有解&#xff0c;如下图所示。 左图为皇后的攻击范围&#xff0c;右图为一个可行解。 2、分析 最简单的思路是把问题转化为 “…...

UE4/UE5 设置widget中text的字体Outline

想要在蓝图中控制Widget 中的 text字体&#xff0c;对字体outline参数进行设置。 但是蓝图中无法直接获取设置outline参数的方法&#xff1a; 没有outline相关的蓝图函数 该参数本身是在Font类别下的扩展&#xff0c;所以只要获取设置Font参数即可进行outline的设置 text连出…...

漏洞复现-phpmyadmin_SQL注入 (CVE-2020-5504)

phpmyadmin SQL注入 _&#xff08;CVE-2020-5504&#xff09; 漏洞信息 CVE-2020-5504sql注入漏洞Phpmyadmin 5.00以下 描述 ​ phpMyAdmin是Phpmyadmin团队的一套免费的、基于Web的MySQL数据库管理工具。该工具能够创建和删除数据库&#xff0c;创建、删除、修改数据库表&…...

安装虚拟机(VMware)保姆级教程及配置虚拟网络编辑器和安装WindowsServer以及宿主机访问虚拟机和配置服务器环境

目录 一、操作系统 1.1.什么是操作系统 1.2.常见操作系统 1.3.个人版本和服务器版本的区别 1.4.Linux的各个版本 二、VMware Wworkstation Pro虚拟机的安装 1.下载与安装 注意&#xff1a;VMWare虚拟网卡 2.配置虚拟网络编辑器 三、安装配置 WindowsServer 1.创建虚拟…...

vue表格列表导出excel

你可以通过下面的步骤使用Vue导出Excel表格&#xff1a; 安装依赖 安装两个依赖包&#xff1a; npm install --save xlsx file-saver创建Excel导出方法 //导出 Excel exportExcel() {// 表格数据let data this.tableData;// 转化为工作簿对象const workbook XLSX.utils.bo…...

CSS基础入门03

目录 1.圆角矩形 1.1基本用法 1.2生成圆形 1.3生成圆角矩形 1.4展开写法 2.Chrome 调试工具--查看 CSS 属性 2.1打开浏览器 2.2标签页含义 2.3elements 标签页使用 3.元素的显示模式 3.1块级元素 3.2行内元素/内联元素 3.3行内元素和块级元素的区别 3.4改变显示模…...

大数据架构设计理论与实践

大数据架构设计理论与实践 大数据处理系统概述 传统数据处理系统存在的问题 大数据处理系统面临的挑战 大数据处理系统的属性/特征 典型的大数据架构 Lambda架构 Lambda定义 优缺点 应用场景 Lambda的体系结构( Batch Layer (批处理层)、Speed Layer (加速层)、Serving Lay…...

2024级199管理类联考之英语二2200核心词汇(第三天)

abstract 抽象的,非具体的 n-摘要ideal adj -理想的 n-理想idealized 理想化的ideology 意识形态,思想体系concept 观念,概念 conception n-构想,怀孕,观念awareness 意识,认识significant 重要的,有意义的 significance n-意义,重要性major v-主修 adj-主要的,成年的 n-成年人…...

SQL中:语法总结(group by,having ,distinct,top,order by,like等等)

语法总结&#xff1a;group by&#xff0c;distinct ...... 1.group by2.聚集函数count 3.order by4.增insert、删&#xff08;drop、delete&#xff09;、改&#xff08;update、alter&#xff09;5.查select嵌套查询不相关子查询相关子查询使用的谓词使用的谓词子查询的相关谓…...

13.计算机视觉

#pic_center R 1 R_1 R1​ R 2 R^2 R2 目录 知识框架No.1 数据增广一、数据增广二、D2L代码注意点三、QA No.2 微调一、微调二、D2L代码注意点三、QA No.3 第二次竞赛 树叶分类结果No.4 实战 Kaggle 比赛&#xff1a;图像分类&#xff08;CIFAR-10&#xff09;一、Kaggle Cifar…...

关于Java中的运算符

文章目录 前言一、什么是运算符二、算术运算符1.基本四则运算符&#xff1a;加减乘除模( - * / %)2.增量运算符( - * /*)3.自增/自减运算符( --) 三、关系运算符四、逻辑运算符1.逻辑&&2.逻辑||3.逻辑非&#xff01;4.短路求值 五、位运算六、移位运算七、条件运算符八…...

细说RTSP、RTMP和GB28181区别

好多流媒体初学者&#xff0c;对RTSP、RTMP和GB28181三者容易混淆&#xff0c;不了解他们的使用场景和区别&#xff0c;本文抛砖引玉&#xff0c;大概介绍下三者的区别。 RTSP&#xff08;Real-Time Streaming Protocol&#xff09;、RTMP&#xff08;Real-Time Messaging Pro…...

Windows下安装Anaconda、Pycharm以及iflycode插件图解

目录 一、下载Anaconda、Pycharm以及iflycode插件 二、创建相关文件夹 三、Pycharm社区版安装详细步骤 四、Anaconda安装详细步骤 五、配置Pycharm 六、安装iflycode插件 Anaconda是一款集成的Python环境&#xff0c;anaconda可以看做Python的一个集成安装&#xff0c;安…...

Steger算法实现结构光光条中心提取(python版本)

Steger算法原理 对结构光进行光条中心提取时,Steger算法是以Hessian矩阵为基础的。它的基础步骤如下所示: 从Hessian矩阵中求出线激光条纹的法线方向在光条纹法线方向上将其灰度分布按照泰勒多项式展开,求取的极大值即为光条在该法线方向上的亚像素坐标。对于二维离散图像来…...

【完整解题】2023年第四届MathorCup高校数学建模挑战赛——大数据竞赛B题 思路代码文章电商零售商家需求预测及库存优化问题

赛道 B&#xff1a; 电商零售商家需求预测及库存优化问题 问题背景&#xff1a; 电商平台存在着上千个商家&#xff0c;他们会将商品货物放在电商配套的仓库&#xff0c; 电商平台会对这些货物进行统一管理。通过科学的管理手段和智能决策&#xff0c; 大数据智能驱动的供应链可…...

服务网络基础

服务网络基础 目录 前言 从今天开始我们将进入服务网格的学习&#xff0c;服务网格是微服务架构中的一种重要的技术&#xff0c;它可以解决微服务架构中的一些问题&#xff0c;比如服务发现、服务治理、服务监控等等&#xff0c;我们将从服务网格的基础开始&#xff0c;逐步深…...

2016年亚太杯APMCM数学建模大赛C题影视评价与定制求解全过程文档及程序

2016年亚太杯APMCM数学建模大赛 C题 影视评价与定制 原题再现 中华人民共和国成立以来&#xff0c;特别是政治改革和经济开放后&#xff0c;随着国家经济的增长、科技的发展和人民生活水平的提高&#xff0c;中国广播电视媒体取得了显著的成就&#xff0c;并得到了迅速的发展…...

Elasticsearch:使用 Open AI 和 Langchain 的 RAG - Retrieval Augmented Generation (四)

这篇博客是之前文章&#xff1a; Elasticsearch&#xff1a;使用 Open AI 和 Langchain 的 RAG - Retrieval Augmented Generation &#xff08;一&#xff09;Elasticsearch&#xff1a;使用 Open AI 和 Langchain 的 RAG - Retrieval Augmented Generation &#xff08;二&a…...

YOLOv7优化:渐近特征金字塔网络(AFPN)| 助力小目标检测

💡💡💡本文改进:渐近特征金字塔网络(AFPN),解决多尺度削弱了非相邻 Level 的融合效果。 AFPN | 亲测在多个数据集能够实现涨点,尤其在小目标数据集。 收录: YOLOv7高阶自研专栏介绍: http://t.csdnimg.cn/tYI0c ✨✨✨前沿最新计算机顶会复现 🚀🚀🚀…...

J2EE项目部署与发布(Windows版本)

&#x1f3ac; 艳艳耶✌️&#xff1a;个人主页 &#x1f525; 个人专栏 &#xff1a;《Spring与Mybatis集成整合》《Vue.js使用》 ⛺️ 越努力 &#xff0c;越幸运。 1.单机项目的部署 1.1们需要将要进行部署的项目共享到虚拟机中 在部署项目之前&#xff0c;我们先要检查一下…...

使用AWS Lambda函数的最佳实践!

主题 函数代码 函数配置 指标和警报 处理流 安全最佳实践 有关 Lambda 应用程序最佳实践的更多信息&#xff0c;请参阅 Serverless Land 中的 Application design。 函数代码 从核心逻辑中分离 Lambda 处理程序。这样您可以创建更容易进行单元测试的函数。在 Node.js 中…...

【计算机毕设小程序案例】基于SpringBoot的小演员招募小程序

前言&#xff1a;我是IT源码社&#xff0c;从事计算机开发行业数年&#xff0c;专注Java领域&#xff0c;专业提供程序设计开发、源码分享、技术指导讲解、定制和毕业设计服务 &#x1f449;IT源码社-SpringBoot优质案例推荐&#x1f448; &#x1f449;IT源码社-小程序优质案例…...

老年少女测试媛入职感想

作为一枚从事通信行业测试的老年少女测试媛&#xff0c;入职离职也有两三次了。现在又在一家企业入职了。虽然心里也清楚离职和入职&#xff0c;无非也就是从一个公司的坑里跳出来&#xff0c;再跳到另外一个公司的坑里罢了&#xff0c;明明知道老东家的坑是填不完的了&#xf…...

StreamSaver.js入门教程:优雅解决前端下载文件的难题

本文简介 点赞 关注 收藏 学会了 本文介绍一个能让前端优雅下载大文件的工具&#xff1a;StreamSaver.js ⚡️ StreamSaver.js GitHub地址⚡️ 官方案例 StreamSaver.js 可用于实现在Web浏览器中直接将大文件流式传输到用户设备的功能。 传统的下载方式可能导致大文件的加…...

element-ui vue2 iframe 嵌入外链新解

效果如图 实现原理 在路由中通过 props 传值 {path: /iframe,component: Layout,meta: { title: 小助手, icon: example },children: [{path: chatglm,name: chatglm,props: { name: chatglm,url: https://chatglm.cn },component: () > import(/views/iframe/common),me…...

win10 + VS2017 编译libjpeg(jpeg-9b)

需要用到的文件&#xff1a; jpeg-9b.zip win32.mak 下载链接链接&#xff1a;https://pan.baidu.com/s/1Z0fwbi74-ZSMjSej-0dV2A 提取码&#xff1a;huhu 步骤1&#xff1a;下载并解压jpeg-9b。 这里把jpeg-9b解压到文件夹"D:\build-libs\jpeg\build\jpeg-9b" …...

如何实现公网远程桌面访问Ubuntu?VNC+cpolar内网穿透!

文章目录 前言1. ubuntu安装VNC2. 设置vnc开机启动3. windows 安装VNC viewer连接工具4. 内网穿透4.1 安装cpolar【支持使用一键脚本命令安装】4.2 创建隧道映射4.3 测试公网远程访问 5. 配置固定TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址5.3 测试…...

SpringMvc接收参数

接受参数:1.路径设置RequestMapping(value"地址",method"请求方式") 类|方法GetMapping PostMapping 方法2.接受参数[重点]param直接接收---handler(类型 形参名) 形参名请求参数名注解指定---handler(RequestParam(name"请求参…...

计算机网络文章荟萃

脑残式网络编程入门(二)&#xff1a;我们在读写Socket时&#xff0c;究竟在读写什么&#xff1f;-网络编程/专项技术区 - 即时通讯开发者社区! 1.什么是 socket - 掘金2.socket 的实现原理 - 掘金本文讲述了 socket 在 linux 操作系统下的数据结构&#xff0c;以及阻塞 IO 利用…...

C# Socket通信从入门到精通(4)——多个异步TCP客户端C#代码实现

前言: 在之前的文章C# Socket通信从入门到精通(3)——单个异步TCP客户端C#代码实现我介绍了单个异步Tcp客户端的c#代码实现,但是有的时候,我们需要连接多个服务器,并且对于每个服务器,我们都有一些比如异步连接、异步发送、异步接收的操作,那么这时候我们使用之前单个…...