n皇后(回溯)

news2024/11/22 23:11:20

著名的n皇后问题

即在棋盘上任意两个皇后不能在同一行,同一列,或者斜对角线,反斜对角线的位置

 以判断(5,1)位置为例

往右下方(斜对角线)一连串的位置 (5,1)(6,2)(7,3)(8,4),(x,y)得到规律

x-y=4 横纵坐标差值相等,与(5,1)5-1==4相等

得到结论(i-a[i]==x-y) 

往右上方(反斜对角线)一连串的位置 (5,1)(4,2)(3,3)(2,4),(1,5),(x,y)得到规律

x+y=6 横纵坐标差值相等,与(5,1)5+1==6相等

得到结论(i+a[i]==x+y)

i从1不断遍历到n行,

a[i]表示第i行上的皇后放于a[i]列上

check函数中x、y表示 第x行的皇后可否存储在第y列上 

#include<cstdio>
#include<cstdlib>
#include<iostream>//a[i]表示第i行上的皇后放于a[i]列上 
using namespace std;//假设a[i]=k,则a[i]表示第i行的皇后存储在第k列的位置上 
const int N=10;
int a[N];
int cnt,n;
bool check(int x,int y)//判断在10行10列的棋盘上,第x行的皇后可否存储在第y列上 
{
	for(int i=1;i<=x;i++)//行从第一行的皇后开始遍历,以每一个皇后为关键点,分别搜索和该皇后同一列的位置
	//a[i]==y 表示  第i行的皇后存储在第y列的位置上,因为任意两个皇后不能在同一列,如果条件成立,返回false,第x行的皇后不能存储在第y列上 
	//i+a[i]==x+y  因为a[i]=k,是第i行皇后的列数,再加上行数i。如果i+k==x+y,则(x,y)位置与第i行的皇后处于同一斜对角线上 ,不成立 
	//i-a[i]==x-y  因为a[i]=k,是第i行皇后的列数,再减去行数i。如果i-k==x-y,则(x,y)位置与第i行的皇后处于同一反斜对角线上,不成立  
	{
		if(a[i]==y)return false;
	    if(i+a[i]==x+y)return false;
		if(i-a[i]==x-y)return false;		
	}
	 return true;//如果前面条件全部不成立,则说明,第x行的皇后可存储在第y列上
	
}
void dfs(int row)//从第1行开始遍历 
{
	if(row==n+1)//因为row从1开始,所以当相等时候,说明找到第n个皇后,cnt表示有多少种皇后摆放方式,每次找到n个皇后,cnt+1 
	{
		cnt++;
		return;
	}
	for(int i=1;i<=n;i++)//这里i是列,对于每一行row的皇后,从左到右依次遍历 
	{
		if(check(row,i))//如果为真表示在第row行的皇后存储在第i列 
		{
			a[row]=i;//将列数存储在a数组中,记录 
			dfs(row+1);//进入深搜 
			a[row]=0;//退出dfs后,回溯还原 
		}
	}
}
int main()
{
	cin>>n;//输入n皇后个数 
	dfs(1);//从1开始 
	cout<<cnt;//输出n皇后摆放种数 
	return 0;
}
 

输入8 得到结果92

再看一个例题

3.2AcWing 843 n-皇后问题

n−皇后问题是指将 n 个皇后放在 n×nn×n 的国际象棋棋盘上,使得皇后不能相互攻击到,即任意两个皇后都不能处于同一行、同一列或同一斜线上。

现在给定整数 nn,请你输出所有的满足条件的棋子摆法。

输入格式

共一行,包含整数 n。

输出格式

每个解决方案占 n 行,每行输出一个长度为 n 的字符串,用来表示完整的棋盘状态。

其中 . 表示某一个位置的方格状态为空,Q 表示某一个位置的方格上摆着皇后。

每个方案输出完成后,输出一个空行。

注意:行末不能有多余空格。

输出方案的顺序任意,只要不重复且没有遗漏即可。

数据范围

1≤n≤91≤n≤9

输入样例:

4

输出样例:

.Q..

...Q

Q...

..Q.

..Q.

Q...

...Q

.Q..

解题思路:顺序就是我们可以向全排列那样搜,因为每一行都有放一个皇后所以我们可以枚举每一行的皇后放在什么位置,这里我们需要注意剪枝,我们也可以先写一个全排列,然后在判断每个皇后的位置。

代码如下:

#include <iostream>
using namespace std;
const int N = 20; 
 
// bool数组用来判断搜索的下一个位置是否可行
// col列,dg对角线,udg反对角线
// g[N][N]用来存路径
 
int n;
char g[N][N];
bool col[N], dg[N], udg[N];
 
void dfs(int u) {
    // u == n 表示已经搜了n行,故输出这条路径
    if (u == n) {
        for (int i = 0; i < n; i ++ ) puts(g[i]);   // 等价于cout << g[i] << endl;
        puts("");  // 换行
        return;
    }
 
    // 枚举u这一行,搜索合法的列
    int x = u;
    for (int y = 0; y < n; y ++ )
        // 剪枝(对于不满足要求的点,不再继续往下搜索)  
        if (col[y] == false && dg[y - x + n] == false && udg[y + x] == false) {
            col[y] = dg[y - x + n] = udg[y + x] = true;
            g[x][y] = 'Q';
            dfs(x + 1);
            g[x][y] = '.';  // 恢复现场
            col[y] = dg[y - x + n] = udg[y + x] = false;
        }
}
 
int main() {
    cin >> n;
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < n; j ++ )
            g[i][j] = '.';
 
    dfs(0);
 
    return 0;
}   
 

重点解析:在斜对角线上的所有坐标 x-y 的值恒相等 ,设为常数字b1,在反斜对角线上的所有坐标 x+y 的值恒相等 ,设为常数字b2,分别用dg[] 和 udg[]两个bool数组表示,dg[b1]=false,表示在棋表中 y=x-b1 的斜对角线上的所有坐标尚未有皇后占领,若皇后在该y=x-b1斜线上出现过一次,则将dg[b1]=false更改为true,表示在y=x-b1斜对角线上位置已被占领,下次在判断条件时,判断到这个斜线y=x-b1对于的dg数组值为true时,就不满足判断条件 +n是因为数组有可能出现负数,加上n,能保证y - x + n的值恒大于等于0 ugb同理

col[],这个从0开始遍历到n-1列,皇后每一相同列只能出现一次

 

本博客是在观看b站 n皇后问题_哔哩哔哩_bilibili

基础上做笔记,如果有侵权,请联系作者,谢谢

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

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

相关文章

Naive-UI自定义TabPane样式

前言前端开发通常使用 第三方 UI 组件库&#xff0c;像大家熟悉的 Element-UI、AntD Vue 等最近发现一个 还比较好用的 组件库 Naive-UI 传送门 &#xff0c;Vue 3 组件库&#xff0c;使用 TypeScript &#xff0c;用起来感觉还不错&#xff0c;它的主题也可以切换 &#xff08…

首款自研成像雷达发布!国产玩家赋能智能驾驶“第四类”感知

4D成像雷达赛道的“战火”正在不断升级。 高工智能汽车研究院预计&#xff0c;4D成像雷达将从2023年初开始小规模前装导入&#xff0c;预计到2024年&#xff0c;定点/搭载量有望突破百万颗&#xff0c;到2025年占全部前向毫米波雷达的比重或超过40%。 伴随着中国自动驾驶的渗…

Java多线程:多线程 Thread 类 中常用的方法的使用

Java多线程&#xff1a;多线程 Thread 类 中常用的方法的使用 每博一文案 日本有一位方丈曾在其寺庙的公告栏上写下一句标语&#xff1a; ”没有失败的人生才最失败。“ 深以为然&#xff0c;不上高山&#xff0c;不知平地&#xff0c;不经大海&#xff0c;不懂宽阔的涵义&…

很少人知道的7个极酷HTML元素

搜索很酷的HTML元素&#xff0c;尤其是当您不知道要查找什么时&#xff0c;通常就像被扔进一堆垃圾中一样动图别担心&#xff0c;我为你做了肮脏的工作&#xff01;在浏览了看似无穷无尽的HTML元素之后&#xff0c;我挖出了一些很少使用的宝石&#xff01;1. meter&progres…

多线程Monitor工作原理

&#x1f34e;1. 什么是Monitor?我们都知道synchronized的作用是用来保证修饰的代码或者方法执行有且只有一个线程执行&#xff0c;也就是锁。那么在执行被锁住的方式时&#xff0c;synchronized就需要通过monitor来记录和保证锁的状态。所以monitor这里的作用其实就是起到了控…

RFID固定资产管理系统实现批量“秒”级盘点

面对成千上万&#xff0c;乃至几十万的固定资产&#xff0c;如何能高效管理&#xff0c;做到管理无漏洞&#xff0c;盘点无错漏呢&#xff1f;很多企业和软件厂商都在考虑这个问题。现如今&#xff0c;随着物联网的发展&#xff0c;企业可批量实现固定资产的秒级盘点&#xff0…

【C++核心编程】C++全栈体系(十一)

C核心编程 第四章 类和对象 七、多态 1. 多态的基本概念 多态是C面向对象三大特性之一 多态分为两类 静态多态: 函数重载 和 运算符重载属于静态多态&#xff0c;复用函数名动态多态: 派生类和虚函数实现运行时多态 静态多态和动态多态区别&#xff1a; 静态多态的函数…

打印机共享遇到的常见问题与解决方法

共享打印机提示错误0X000006d9 解决方法: 1、桌面找到计算机或此电脑,然后再图标上右键选择管理选项菜单; 2、在打开的计算机管理对话框中选择服务和应用程序选项; 3、双击服务和应用程序选项就会打开一个对话框,然后再选择服务菜单双击;

01-JDK、JRE、JVM之间的区别?

1.JDK JDK(Java SE Development Kit)&#xff0c;Java标准开发包&#xff0c;它提供了编译、运⾏Java程序所需的各种⼯具和资源&#xff0c;包括Java编译器、Java运⾏时环境&#xff0c;以及常⽤的Java类库等. JDK安装目录中真正在运行java时起作用的是 bin、include、lib、…

一网打尽链表的经典OJ题!链表必考笔试题第二弹

目录 0.前言 1.合并两个排序链表 1.1 实用小妙招 1.2代码书写 2.链表分割 3.链表的回文结构 4.相交链表 4.1 实用小妙招&#xff08;假定指针法&#xff09; 4.2代码书写 5. 复制带随机指针的链表 0.前言 本文代码及分析图片资源都以上传Gitee&#xff0c;可自取&a…

【Java数据结构】堆与优先级队列(堆)的详解

文章目录 目录 文章目录 一、优先级队列(堆) 1.1优先级队列的概念 二、优先级队列的模拟实现 2.1堆的概念 2.2堆的存储方式 2.3堆的创建 2.4建堆的时间复杂度 2.5堆的插入和删除 三.常用的PriorityQueue介绍 3.1PriorityQueue特性 3.2PriorityQueue常用方法 3.3oj练习 一、优…

CANoe-Model Editor介绍以及如何创建一个服务

Model Editor,模型编辑器,可以打开导入的ARXML文件,编辑现有的或定义新的应用层对象(CO、DO) 什么是CO和DO? Model Editor页面的整体布局为: 在左侧的子窗口中,你可以选择要编辑的内容根据你的选择,相应的内容将显示在右侧根据你在此处的选择,你可以使用其他拆分器来…

Vue--》Vue3的setup语法糖到底香不香?你来看看就知道了

目录 setup语法糖 创建Vue3项目 setup语法糖的使用 快速生成setup语法糖模板 setup语法糖新增的API useSlots()和useAttrs() 顶层await setup语法糖 相信在了解过这篇文章的 setup函数讲解 人会觉得Vue3处理数据变得繁琐了&#xff0c;所有的变量都必须return出来才能使…

8步,用python实现进行自动化评论、点赞、关注脚本

嗨害大家好鸭&#xff01; 我是小熊猫~ 分享这个没啥&#xff0c;就是好玩 这里写目录标题嗨害大家好鸭&#xff01; 我是小熊猫~开发环境代码实现点击此处跳转文末名片获取1.请求伪装2.获取关键词3. 获取作品评论ID采集4. 设置评论相应内容5. 设置点赞操作6. 设置关注操作7. 获…

数据结构实验头歌 第1关:求图的最短路径

任务描述 本关任务&#xff1a;编程实现求图的最短路径 相关知识 最短路径的Dijkstra算法&#xff1a; 求最短路径就是求图中的每一个点到图中某一个给定点&#xff08;认为编号为0的点&#xff09;的最短距离。 具体算法就是初始有一个旧图&#xff0c;一个新图。开始时旧图中…

Linux项目自动化构建工具-make/Makefifile

目录 背景 实例代码 依赖关系 依赖方法 原理 项目清理 可重复执行的依据 背景 会不会写makefile&#xff0c;从一个侧面说明了一个人是否具备完成大型工程的能力 一个工程中的源文件不计数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;makefile定义了一系…

K8s部署前后端分离项目(一)

K8s部署前后端分离项目 环境准备 K8s环境 主节点master&#xff1a;192.168.3.200 子节点node1&#xff1a;192.168.3.201 子节点node2&#xff1a;192.168.3.202 Harbor远程仓库 已部署在master主节点上&#xff0c;目录为&#xff1a;cd /workspace/harbor/harbor 1、登录地…

java使用XDocReport导出word

使用XDocReport 导出word效果word编辑器案例word模板模板制作解决图片不存在时, "现场照片" 列被隐藏问题依赖返回数据对象 DailyRecordReportOpinionVO 审核记录对象PicVo 图片对象导出接口效果 说明: “现场图片” 为动态图片列表 , “专业负责人审核意见” 和 “项…

freeswitch的多租户模式

概述 freeswitch是一款简单好用的VOIP开源软交换平台。 现在的VOIP服务越来越倾向于云端服务&#xff0c;包括呼叫中心云服务&#xff0c;线路云平台。 而云平台对多个客户的服务就需要做好隔离&#xff0c;包括数据隔离、线路隔离、服务隔离等。 freeswitch内部的多租户模…

如何给视频批量添加背景图的实例操作教程

如何给视频添加上背景图片呢&#xff1f;有需要的宝宝跟着小编一起来看看怎么操作的吧。 先运行【云炫AI智剪】&#xff0c;然后再选择画中画&#xff0c;切换相对应的界面当中。 接下来把底画背景图导入到列表中&#xff0c;可以选中文件直接拖动到软件中&#xff0c;或者…