【第十八课】DFS:深度优先搜索( acwing-843 n-皇后问题 / c++代码 )

目录

错误写法(可跳

DFS-剪枝

代码

思路二: 原始解法


 

错误写法(可跳

看到这道题,我想这不还是n个数的全排列的问题么?也就是把数字变成了字符,一些输出格式上的变化。于是就在原有代码上修改一下应该就行。

我的思路就还是path存有可能的排序路径,但是输出的时候要输出字符,且为棋盘格的二维数组形式,因此添加了两层for循环嵌套,并用if语句判断 path[i]==j ,说明此处放皇后Q,符合输出格式。

代码

#include<iostream>
using namespace std;
const int N=12;
int n;
int path[N];
bool st[N];void dfs(int x)
{if(x==n){for(int i=0;i<n-1;i++)//只判断了相邻两个皇后是否处于同一斜线{//由于数组会索引到i+1 因此第二个表达式应该是i<n-1if(path[i]-path[i+1]==1 || path[i]-path[i+1]==-1)return;}for(int i=0;i<n;i++){for(int j=0;j<n;j++){if(path[i]==j){printf("Q");}else{printf(".");}}puts("");}puts("");return;}for(int i=0;i<n;i++){if(!st[i]){st[i]=1;path[x]=i;dfs(x+1);st[i]=0;}}
}
int main()
{scanf("%d",&n);dfs(0);return 0;
}

这里错误的原因在于,我通过在得到一种答案输出之前,

for(int i=0;i<n-1;i++)//只判断了相邻两个皇后是否处于同一斜线{if(path[i]-path[i+1]==1 || path[i]-path[i+1]==-1)return;}

判断相邻两个皇后的数字相差不能是1或-1,也就是限制了相邻两个皇后的位置不能是对角线或者副对角线的关系。

但是题目要求的是任何两个皇后都不能呈对角线或副对角线的关系。因此这样的写法是不符合题意的虽然有些情况下会输出正确结果,但是正确率极低。只能说是忘记模板的话能蹭一点点分😂。

ok正文开始~

DFS-剪枝

我们观察到这是一个在 n个数的全排列 框架之下的问题。我们需要注意的就是

1.输入输出格式是字符因此我们考虑把原来的path存储答案的序列改为 char 类型的 g[N][N]  二维数组,也方便符合条件的输入输出。

首先要将二维棋盘格初始化全为 '.' ,利用两层for循环嵌套。输出的时候可以直接输出 g[i] 表示输出一行的字符串

其次在dfs恢复现场的时候, g[u][i]='.' 也要恢复。因为我们在搜索过程中修改了棋盘的状态。当我们从一个节点回溯到它的父节点时,我们需要把棋盘恢复到父节点的状态,以便于搜索父节点的其他子节点。

在单纯的数字全排列问题中我们会不断地在同一位置尝试不同的数字,因此前一个数字会被后一个数字覆盖。这个过程并不需要我们手动去恢复,因为每次尝试新的数字时,旧的数字自然就被"覆盖"了

2.任意两个皇后都不能处于同一行、同一列或同一斜线上

这是区别于模板的最主要的题设。有了这些限制,我们就要多加限制条件,去掉一些不满足条件的答案,称“剪枝”。

由于我们是以行为基准,每一次递归调用dfs(u+1)都会使得行数u增加1,这样就保证了每一行只有一个皇后。因此,我们并不需要额外的数组来检查是否有多个皇后在同一行。我们需要另外定义col数组表示列,dg数组表示对角线,udg数组表示主对角线。 

col数组的坐标直接是 i  表示列,那么如何表示对角线呢

在一个二维平面上,一条直线的斜率和截距可以唯一确定这条直线。在这个问题中,我们的直线其实就是棋盘上的对角线,斜率固定为1或-1(因为对角线的斜率是固定的),所以我们只需要找到一个唯一的截距就可以确定一条对角线

 

代码中u就表示行,i 表示列。由此得出dg udg 的下标表示 

for(int i=0;i<n;i++){if(!col[i] && !dg[u+i] && !udg[n-u+i]){g[u][i]='Q';//用u来表示行,变化的是第u行中的某个元素col[i]=dg[u+i]=udg[n-u+i]=1;dfs(u+1);//通过递归确保了每一行放一个皇后g[u][i]='.';//恢复现场col[i]=dg[u+i]=udg[n-u+i]=0;}}

代码

#include<iostream>
using namespace std;
const int N=12;
int n;
char g[N][N];
bool col[N],dg[N],udg[N];void dfs(int u)
{if(u==n){for(int i=0;i<n;i++){puts(g[i]);}puts("");return;}for(int i=0;i<n;i++){if(!col[i] && !dg[u+i] && !udg[n-u+i]){g[u][i]='Q';//用u来表示行,变化的是第u行中的某个元素col[i]=dg[u+i]=udg[n-u+i]=1;dfs(u+1);//通过递归确保了每一行放一个皇后g[u][i]='.';//恢复现场col[i]=dg[u+i]=udg[n-u+i]=0;}}
}
int main()
{scanf("%d",&n);for(int i=0;i<n;i++){for(int j=0;j<n;j++){g[i][j]='.';}}dfs(0);return 0;
}

思路二: 原始解法

先放代码,思路之后回来补写,,

#include<iostream>
using namespace std;
const int N=12;
int n;
char g[N][N];
bool row[N],col[N],dg[N],udg[N];void dfs(int x,int y,int s)
{if(y==n)//该行已经遍历完了,因此列标要重新从0开始,行数+1{y=0;x++;}if(x==n)//当行数也遍历完{if(s==n)//先判断皇后数量是否符合题意{for(int i=0;i<n;i++)//满足条件说明得一个答案{puts(g[i]);}puts("");}return;}//不放皇后dfs(x,y+1,s);//如果满足这些条件才会放皇后if(!row[x] && !col[y] && !dg[x+y] && !udg[x-y+n]){g[x][y]='Q';row[x]=col[y]=dg[x+y]=udg[x-y+n]=1;dfs(x,y+1,s+1);row[x]=col[y]=dg[x+y]=udg[x-y+n]=0;g[x][y]='.';}
}
int main()
{scanf("%d",&n);for(int i=0;i<n;i++){for(int j=0;j<n;j++){g[i][j]='.';}}dfs(0,0,0);//从第0行第0列即左上角开始搜,此时皇后数量为0return 0;
}

先写到这咯,状态不太好,下午先休息了emmm

有问题欢迎指出!!一起加油!!

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

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

相关文章

跨站脚本攻击漏洞概述-XSS

什么是跨站脚本攻击 跨站脚本( Cross-site Scripting ) 攻击&#xff0c;攻击者通过网站注入点注入客户端可执行解析的payload(脚本代码)&#xff0c;当用户访问网页时&#xff0c;恶意payload自动加载并执行&#xff0c;以达到攻击者目的(窃取cookie、恶意传播、钓鱼欺骗等)。…

十大排序算法之非线性时间比较类排序

前言 接下来就开始我们的算法学习之路了&#xff0c;代码会分别使用Java与Python来实现&#xff0c;数据处理的算法很多&#xff0c;排序是最基础且最重要的一类&#xff0c;大多数人都是通过学习排序算法入门的。接下来让我们一起学习闻名遐迩的十大排序算法&#xff0c;它们…

非官方 Bevy 作弊书07-09

源自 网页 Working with 2D - Unofficial Bevy Cheat Book 个人用 有道 翻译&#xff0c;希望能够帮助像我一样的 英语不好 的 bevy 初学者 非官方 Bevy 作弊书 7 使用 bevy 2D 本章涵盖与使用 Bevy 制作 2D 游戏相关的主题。 2D Camera Setup - Unofficial Bevy Cheat Book 非…

【LeetCode: Z 字形变换 + 模拟】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

Redis学习——高级篇②

Redis学习——高级篇② Redis7高级之BigKey&#xff08;二&#xff09; 1.MoreKey案例2.BigKey案例2.1 多大算 BigKey以及它的危害2.2 如何产生、发现、删除 3. bigKey生产调优 Redis7高级之BigKey&#xff08;二&#xff09; 1.MoreKe…

【高效开发工具系列】Java读取Html

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Linux系统安装Nginx

一、Nginx的简介 Nginx是一个高性能的HTTP和反向代理web服务器&#xff0c;是由伊戈尔赛索耶夫为俄罗斯访问量第二站点开发的&#xff0c;因它的稳定性、丰富的功能集、简单的配置文件和低系统资源的消耗而闻名&#xff0c;第一个公开版本0.1.0发布于2004年10月4日。 Nginx是一…

C# RichTextBox常用属性、方法学习1

1 字体 Font font1 new Font("宋体", 18); richTextBox1.Font font1; Font font2 new Font("宋体", 10, FontStyle.Underline); richTextBox1.SelectionFont font2; 定义字体&#xff0c;可以带2个参数&#…

LeetCode---122双周赛

题目列表 3010. 将数组分成最小总代价的子数组 I 3011. 判断一个数组是否可以变为有序 3012. 通过操作使数组长度最小 3013. 将数组分成最小总代价的子数组 II 一、将数组分成最小总代价的子数组I 这道题纯纯阅读理解题&#xff0c;关键在于理解题意。注意&#xff1a;第一…

总体方差与样本方差的区别是什么?

总体方差和样本方差是统计学中两个重要概念&#xff0c;它们在定义和计算上有所不同&#xff0c;主要区别体现在数据集的性质和计算公式的分母上&#xff1a; 1. 总体方差&#xff08;Population Variance&#xff09;&#xff1a; 定义&#xff1a; 总体方差是指将一个完整数…

嵌入式——窗口看门狗(WWDG)补充

目录 一、独立看门狗与窗口看门狗 1.功能描述 2.两者区别 二、WWDG功能描述 1.窗口看门狗时钟 2.计数器时钟 3. 计数器 4.窗口值 三、WWDG超时时间 一、独立看门狗与窗口看门狗 1.功能描述 STM32有两个看门狗&#xff1a;一个是独立看门狗&#xff08;IWDG&#xff0…

数据结构三:线性表之单链表(带头结点单向)的设计与实现

线性表的链式存储结构正是所谓的单链表&#xff0c;何谓单链表&#xff1f;通过地址将每一个数据元素串起来&#xff0c;进行使用&#xff0c;这可以弥补顺序表在进行任意位置的插入和删除需要进行大量的数据元素移动的缺点&#xff0c;只需要修改指针的指向即可&#xff1b;单…

网络编程套接字(2)

UDP数据报套接字编程 API介绍 DatagramSocket DatagramSocket是UDP的Socket,用于发送和接收数据报. 操作系统中有一类文件,就叫做socket文件(普通文件/目录文件:在硬盘上的) socket文件:抽象的表示了网卡这样的硬件设备 DatagramSocket就是对socket文件进行读写,也就是借助网…

对于gzip的了解

gzip基本操作原理&#xff1a;通过消除文件中的冗余信息&#xff0c;使用哈夫曼编码等算法&#xff0c;将文件体积压缩到最小。这种数据压缩方式在网络传输中发挥了巨大作用&#xff0c;减小了传输数据的大小&#xff0c;从而提高了网页加载速度。 静态资源 Vue Vue CLl修改v…

WordPress如何使用SQL实现一键关闭/开启评论功能(已有评论)

WordPress本人就自带评论功能&#xff0c;不过由于种种原因&#xff0c;有些站长不想开启评论功能&#xff0c;那么应该怎么实现一键关闭评论功能或开启评论功能呢&#xff1f;或者针对已有评论功能的文章进行一键关闭或开启评论功能应该怎么操作&#xff1f; 如果你使用的Wor…

【.NET Core】深入理解C#中的特殊字符

【.NET Core】深入理解C#中的特殊字符 文章目录 【.NET Core】深入理解C#中的特殊字符一、概述二、$-- 字符串内插2.1 内插字符串的结构2.2 内插原始字符串字面量2.3 特殊字符2.4 内插字符串编译 三、-- 逐字字符串标识符四、“”“--原始字符串文本 一、概述 特殊字符是预定义…

OpenGL/C++_学习笔记(四)空间概念与摄像头

汇总页 上一篇: OpenGL/C_学习笔记&#xff08;三&#xff09; 绘制第一个图形 OpenGL/C_学习笔记&#xff08;四&#xff09;空间概念与摄像头 空间概念与摄像头前置科技树: 线性代数空间概念流程简述各空间相关概念详述 空间概念与摄像头 前置科技树: 线性代数 矩阵/向量定…

RPC教程 5.支持HTTP协议

1.HTTP的CONNECT方法 Web 开发中&#xff0c;我们经常使用 HTTP 协议中的 HEAD、GET、POST 等方式发送请求&#xff0c;等待响应。但 RPC 的消息格式与标准的 HTTP 协议并不兼容&#xff0c;在这种情况下&#xff0c;就需要一个协议的转换过程。HTTP 协议的 CONNECT 方法提供了…

MybatisPlus二级映射和关联对象ResultMap

文章目录 一、业务背景1. 数据库表结构2. 需求 二、使用映射直接得到指定结构三、其他文件1. Mapper2. Service3. Controller 四、概念理解一级映射二级映射聚合 五、标签使用1. \<collection\> 标签2. \<association\> 标签 在我们的教程中&#xff0c;我们设计了…

flask框架制作前端网页作为GUI

一、语法和原理 &#xff08;一&#xff09;、文件目录结构 需要注意的问题&#xff1a;启动文件命名必须是app.py。 一个典型的Flask应用通常包含以下几个基本文件和文件夹&#xff1a; app.py&#xff1a;应用的入口文件&#xff0c;包含了应用的初始化和配置。 requirem…