当前位置: 首页 > 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;我们先要检查一下…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数&#xff0c;对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分&#xff1a; 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...

mac:大模型系列测试

0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何&#xff0c;是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试&#xff0c;是可以跑通文章里面的代码。训练速度也是很快的。 注意…...