n-皇后问题(DFS深搜两种解法)

news2024/10/7 8:30:02

题目描述: 


思路:

根据题目要求:即任意两个皇后都不能处于同一行、同一列或同一斜线上。我们可以画图去看一下。对角线之间有什么规律可以发掘出来。接下来请看图解

根据上述图片,我们可以把正对角线看成撇对角线,也就是红色线的那个,接下来把反对角线看成是捺对角线,我们可以发现,只要在一个斜线上的数就是一样的,无论是撇对角线,还是捺对角线,这样我们就有了一个条件,还需要保证行和列上不冲突。我们再来往后看看还能发现什么特殊的点呢,如下图

 

我们其实还可以把所谓的撇对角线,捺对角线类比成一次函数,y = kx+b形式, 固定斜率一个是-1一个是1,那么第一个图中的红色线的就是y = -x + b --> b = x + y

第一个图中蓝线 的部分就是y = x + b ---> b = y - x,由于y-x可能出现负数情况,所以我们加一个偏移量n,这样就变成b = y - x + n。

所以我们把需要创建一个bool型 撇捺数组,把用过且不能的放的点标记上1,两个线确定一个点,此点的撇捺线上都不可以放皇后。

 根据第一个图里的数字,我们还可以求出撇捺数组的数据范围是2*n和2*n-1


解法:

此题有两种解法,两种解法的去别在于搜索的顺序不同,第一个解法时间短(按行枚举),第二种解法时间长(每个位置都枚举)。


第一种解法: 

我们去按行枚举,也是按照下图(是一个4*4的棋盘)解释,比如我们第一个肯定是先走(1,1)这块,

接着去枚举第二行,第一个位置是(2,1)不行因为列上已经有(1,1)

继续接着走,走到(2,2)这个位置,也不可以,在捺对角线上,

继续走到(2,3),这个点可以。

接着枚举第三行,第一个位置同理不可以,第二个位置(3,2),与(2,3)在同一个撇对角线上不行,接着走(3,4),不可以与(2,3)冲突

所以回到上一个空间也就是第二行,让其接着上次我们走到的(2,3)接着往后走到(2,4),

然后接着去枚举第三行,走着走着,发现(3,2)可以。

那么就第四行,(4,1)这个点和(1,1)冲突,(4,2)和(3,2)冲突,(4,3)和(3,2)冲突,因为在捺对角线上,都不行就回到上一个空间,按照上一个空间皇后的位置接着往后挪,以此类推,这里就不再赘述


通过上面我们可以发现,一 一去枚举行,然后和放皇后的位置,在撇对角线和捺对角线上只要斜线上值相等,那对不起,你不能放这里。

 这个树帮助理解,大家按照深度优先搜索去自己走一遍

AC代码: 

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 10;
char g[N][N];
//col:列,dg:正下划线,udg:反下划线
bool col[N],dg[N*2],udg[N*2];
int n;

void dfs(int u)
{
    //满足情况输出一下
    if(u==n)
    {
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                cout << g[i][j];
            }
            cout << endl;
        }
        cout << endl;
        return;
    }
    //枚举列数
    for(int i=0;i<n;i++)
    {
        //行列的映射关系
        if(!col[i]&&!dg[i+u]&&!udg[i-u+n])
        {
            g[u][i] = 'Q';
            col[i] = dg[i+u] = udg[i-u+n] = true;
            dfs(u+1);
            col[i] = dg[i+u] = udg[i-u+n] = false;
            g[u][i] = '.';
        }
    }
}

int main()
{
    cin.tie(0)->ios::sync_with_stdio(false);
    cin >> n;
    //初始化
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            g[i][j] = '.';
        }
    }
    dfs(0);//按行搜索
    return 0;
}

 第二种解法:

这种方法,我们就按照一行一列,一个方块一个方块去枚举,包括每个撇对角线,捺对角线

每一个地方两种情况,根据放还是不放去搜索即可


AC代码: 

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 10;
char g[N][N];
bool col[N*2],row[N*2],dg[N*2],udg[N*2];
int n;
//深搜放和不放
void dfs(int x,int y,int s)
{
    //以行为基准,去遍历列相当于一行下遍历n个列
    if(y == n) {
        y = 0,x++;
    }
    //n行搜完输出一下结果
    if(x == n)
    {
        if(s == n)//确保皇后全部摆上
        {
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<n;j++)
                {
                    cout << g[i][j];
                }
                cout << endl;
            }
            cout << endl;
        }
        //注意return的位置,不能放在第二个if里,因为假如s不满足就退不回去上一个空间了
        return;
    }
    //不放
    dfs(x,y+1,s);
    //放
    if(!row[x]&&!col[y]&&!dg[x+y]&&!udg[y-x+n])
    {
        g[x][y] = 'Q';
        row[x] = col[y] = dg[x+y] = udg[y-x+n] = true;
        dfs(x,y+1,s+1);
        //恢复现场
        row[x] = col[y] = dg[x+y] = udg[y-x+n] = false;
        g[x][y] = '.';
    }
    
}

int main()
{
    cin.tie(0)->ios::sync_with_stdio(false);
    cin >> n;
    //初始化
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            g[i][j] = '.';
        }
    }
    //行,列,放皇后的数量
    dfs(0,0,0);
    return 0;
}

 以上部分图片来源于B站董晓算法,有的地方是自己的个人理解,如果有错误,欢迎指出,喜欢的小伙伴可以留个关注~

这个题会的可以去做洛谷P1219

推荐AcWing 843. n-皇后问题--图解+代码注释 - AcWing

和哔哩哔哩董晓算法n-皇后问题

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

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

相关文章

分享300套常用的多行业商城模板和电商模板

小程序商城模板平台&#xff01;免费用多行业商城模板和电商模板&#xff0c;含小程序商城模板&#xff0c;多款精美高端电商模板免费使用&#xff0c;注册即用免费电商模板开发在线商城。 https://www.erdangjiade.com/templates/4-0-0-0-0-0 实现微信小程序携程首页顶部的界…

通过修改ospf的COST值来控制路由选路

配置好OSPF之后,发现默认走的是上面 PC1>tracert 192.168.200.1traceroute to 192.168.200.1, 8 hops max (ICMP), press Ctrl+C to stop1 192.168.100.254 16 ms <1 ms 16 ms2 10.10.10.2 15 ms &l

python入门题:输入输出练习

以下是Python基础语法的练习&#xff0c;项目要求和代码如下&#xff1a; """ 例3&#xff1a;小精灵&#xff1a;你好&#xff0c;欢迎古灵阁&#xff0c;请问您需要帮助吗&#xff1f;需要or不需要&#xff1f; 你&#xff1a;需要 小精灵&#xff1a;请问你需…

AutoCAD 2025(CAD2025)激活版

AutoCAD 2025 是一款由 Autodesk 公司开发的计算机辅助设计&#xff08;CAD&#xff09;软件。它广泛应用于建筑设计、机械制造、土木工程等领域。 AutoCAD 2025 提供了强大的绘图和设计工具&#xff0c;使用户能够创建精确的二维和三维图形。它支持多种绘图方式&#xff0c;如…

IDEA2023版本创建spring boot项目时,Java版本无法选择Java8问题解决

先简单说下出现本问题的原因&#xff1a; spring boot3.0发布时提到未来Java17将会成为主流版本&#xff0c;所有的Java EE Api都需要迁移到Jakarta EE上来。而spring boot3.0及以上版本已经不支持Java8了&#xff0c;支持Java17及以上版本。同时官方支持项目初始化的 Spring B…

Unity数独完整源码

支持的Unity版本&#xff1a;2018.1或更高。 这是一套完整且高效的数独源码&#xff0c;默认是9x9&#xff0c;有上千种关卡文件&#xff0c;4种难度&#xff0c;内有关卡编辑器&#xff0c;可扩展至4x4、6x6的关卡&#xff0c;还有英文文档对源码各方面可配置的地方进行说明&…

openGauss + Datakit搭建openGauss运维平台

系统架构OS 硬件需求&#xff1a;2c4g [rootlocalhost ~]# cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core) [rootlocalhost ~]# uname -m x86_64 [rootlocalhost ~]# hostname -I 192.168.92.32 下载地址&#xff1a;https://opengauss.org/zh/download/ 下载…

Django之Web应用架构模式

一、Web应用架构模式 在开发Web应用中,有两种模式 1.1、前后端不分离 在前后端不分离的应用模式中,前端页面看到的效果都是由后端控制,由后端渲染页面或重定向,也就是后端需要控制前端的展示。前端与后端的耦合度很高 1.2、前后端分离 在前后端分离的应用模式中,后端仅返…

搜索树概念及操作

目录 一. .搜索树 1.1 概念 1.2 操作1 查找 1.3 操作2 插入 1.4 操作3 删除 1.5 性能分析 1.6 和 java 类集的关系 一. .搜索树 1.1 概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树 : 若它的左子树不为空&#x…

C语言程序练习——汉诺塔递归

1. 题目 在终端输入汉诺塔层数n&#xff0c;实现将n层汉诺塔通过三座塔座A、B、C进行排列 2. 代码 #include <stdio.h>int hannuota(int len, int str, int tmp, int dst) {if (1 len){printf("%c -> %c\n", str, dst);}else{hannuota(len-1, str, dst, …

【每日一题】2024年3月汇编(上)

3.1【2369】检查数组是否存在有效划分 2369. 检查数组是否存在有效划分https://leetcode.cn/problems/check-if-there-is-a-valid-partition-for-the-array/ 1.这样的判断可以用动态规划来解决&#xff0c;用一个长度为(n1) 的数组来记录 是否存在有效划分&#xff0c;dp[i]…

单页面应用部署到iis上可以正常打开,刷新就404

当您遇到Dumi打包的网站部署到IIS上可以正常打开首页,但刷新页面时出现404错误的情况,这通常与以下几个方面有关: 路由处理: Dumi生成的项目通常基于SPA(Single Page Application)架构,使用前端路由来实现无刷新导航。这意味着大部分页面切换是在浏览器层面完成的,而不…

循环神经网络(RNN):处理序列数据的利器

目录 1. 引言 2.RNN原理与时间步展开 3.LSTM与GRU工作机制与优势 3.1.LSTM&#xff08;Long Short-Term Memory&#xff09; 3.2.GRU&#xff08;Gated Recurrent Unit&#xff09; 4.应用案例 4.1文本生成 4.2情感分析 5.总结 1. 引言 循环神经网络&#xff08;Recurr…

el-select动态禁用

在一个el-form表单中有5个el-form-item; 每个el-form-item是一个el-select控件&#xff1b; 这5个el-select控件遵循这样的规则&#xff0c;都是使用同一个list集合&#xff0c;如果第一个el-select选择了list中的某一项&#xff0c;那么这一项就被禁用&#xff1b;其他的el-…

【3D目标检测】Det3d—SE-SSD模型训练(前篇):KITTI数据集训练

SE-SSD模型训练 1 基于Det3d搭建SE-SSD环境2 自定义数据准备2.1 自定义数据集标注2.2 训练数据生成2.3 数据集分割 3 训练KITTI数据集3.1 数据准备3.2 配置修改3.3 模型训练 1 基于Det3d搭建SE-SSD环境 Det3D环境搭建参考&#xff1a;【3D目标检测】环境搭建&#xff08;OpenP…

【Entity Framework】Code First 数据批注

【Entity Framework】Code First 数据批注 文章目录 【Entity Framework】Code First 数据批注一、概述二、模型二、键Key三、组合键四、外键-ForeigKey第一种&#xff1a;指定导航属性&#xff0c;会自动生成外键&#xff0c;命名规则为&#xff1a;“对象名称_主键名“第二种…

YOLOv9改进策略:注意力机制 | 二阶通道注意力机制(Second-order Channel Attention,SOCA),实现单图超分效果

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文改进内容&#xff1a;CVPR_2019 SOCA注意力&#xff0c;一种基于二阶通道注意力机制&#xff0c;能够单幅图像超分辨率&#xff0c;从原理角度分析能够在小目标检测领域实现大幅涨点效果&#xff01;&#xff01;&#xff01; &am…

文件编辑命令—vim

1.vim vim 是vi的升级版本.vi 文件名(vi方向键用不了) vim 的官方网站 (welcome home : vim online) 自己也说 vim 是一个程序开发工具而不是文字处理软件。 2.安装vim sudo apt install vim 如果出错了:apt update:刷新软件源; 出现"无法获得锁 之类的"sudo rm 文件…

Vit Transformer

一 VitTransformer 介绍 vit : An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale 论文是基于Attention Is All You Need&#xff0c;由于图像数据和词数据数据格式不一样&#xff0c;经典的transformer不能处理图像数据&#xff0c;在视觉领域的应…

【jenkins+cmake+svn管理c++项目】Windows环境安装以及工具配置

一、目标和环境 目标&#xff1a;搭建一个jenkins环境&#xff0c;实现jenkins调用cmake和svn和VS编译c项目&#xff0c;并将生成的库上传svn。 环境&#xff1a;win10虚拟机&#xff08;练习流程用&#xff0c;正式用的话还是放到服务器&#xff09;&#xff0c;VS2017. 二、…