洛谷P1219 [USACO1.5] 八皇后【n皇后问题】【深搜+回溯 经典题】【附O(1)方法】

P1219 [USACO1.5] 八皇后 Checker Challenge

  • 前言
  • 题目
    • 题目描述
    • 输入格式
    • 输出格式
    • 样例 #1
      • 样例输入 #1
      • 样例输出 #1
    • 提示
    • 题目分析
    • 注意事项
  • 代码
    • 深搜+回溯
    • 打表
  • 后话
    • 额外测试用例
      • 样例输入 #2
      • 样例输出 #2
    • 王婆卖瓜
  • 题目来源

前言

也是说到做到,来做搜索的题(虽然有点拖,但是无伤大雅)。
八皇后,经典的搜索和回溯题,只要学数据结构或者算法基本都会拿出来讲上一嘴或者做一做。想当年说数据结构时对深搜还不太明白,但是学算法时竟然没有看任何提示和题解就自己把n皇后做出来了,当时就很高兴,感觉自己进步了很多。
现在我们就来重温一下这道经典的题目吧!

题目

题目描述

一个如下的 6 × 6 6 \times 6 6×6 的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行、每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子。

上面的布局可以用序列 2 4 6 1 3 5 2\ 4\ 6\ 1\ 3\ 5 2 4 6 1 3 5 来描述,第 i i i 个数字表示在第 i i i 行的相应位置有一个棋子,如下:

行号 1 2 3 4 5 6 1\ 2\ 3\ 4\ 5\ 6 1 2 3 4 5 6

列号 2 4 6 1 3 5 2\ 4\ 6\ 1\ 3\ 5 2 4 6 1 3 5

这只是棋子放置的一个解。请编一个程序找出所有棋子放置的解。
并把它们以上面的序列方法输出,解按字典顺序排列。
请输出前 3 3 3 个解。最后一行是解的总个数。

输入格式

一行一个正整数 n n n,表示棋盘是 n × n n \times n n×n 大小的。

输出格式

前三行为前三个解,每个解的两个数字之间用一个空格隔开。第四行只有一个数字,表示解的总数。

样例 #1

样例输入 #1

6

样例输出 #1

2 4 6 1 3 5
3 6 2 5 1 4
4 1 5 2 6 3
4

提示

【数据范围】
对于 100 % 100\% 100% 的数据, 6 ≤ n ≤ 13 6 \le n \le 13 6n13

题目翻译来自NOCOW。

题目分析

  很容易想到使用深搜+回溯,或者换简单来说,使用递归的方法,每层递归就对应一行,一行一行下来,到达最后一行都可行就在统计上加一。然后我们就需要确定哪个点是可行点。
  难点就在对对角线的判断。新的皇后是点(index,i),我们要判断他和上面任意一个皇后(j,queen[j])不在同一条对角线上,那么就是既不在y=x+a上,也不在y=-x+a上,我们可以发现第一条线y-x和第二条线y+x都恒等于a,所以只要不相等那么就是不在同一条对角线上。所以就有了`queen[j]+j!=i+index&&queen[j]-j!=i-index``
  但是这样复杂度还是有点高呢,因为想要判断与上述所有行能否符合条件,所以过不了最后一个点。需要想出一个方法既然判断符合又只需要判断一次。
  所以我们需要转变思路,本来是每一行的每一个点都需要都要与前面的比较,现在我们想能不能在每个点确定以后就更新一份数组(白名单),使得可以让下次选点在白名单内的就是可行的,于是我们需要确定三个数组,一个是竖列,其他两个是他的向左下和右下的对角线。
然后就拿下了

注意事项

1.只输出前三个解
2.数组开大一些,不要像我只开了13,-_-
3.记得恢复现场(深搜必备注意事项)

代码

深搜+回溯

耶

#include<iostream>
#include<algorithm>
#define MaxN  13//n皇后的最大值 
using namespace std;
int queen[MaxN+1]={0},n,total=0;
int a[25]={0},b[25]={0},c[25]={0};
void printqueen(int queen[MaxN+1]) //打印
{for(int i = 1 ; i <= n; i++) {cout<<queen[i]<<" ";}cout<<endl;}
void dfs(int index) //没有return因为并不是每个dfs都会进入下一层
{if(index==n+1) { //说明已经完成n行,可以计数了total++;if(total<=3)//前三个才打印printqueen(queen);return;}for(int i = 1; i <= n ; i++) {if(!a[i]&&!b[index+i]&&!c[index-i+n]) {queen[index]=i;//存储a[i]=1;b[index+i]=1;c[index-i+n]=1; dfs(index+1);//进入下一层a[i]=0;//恢复 b[index+i]=0;c[index-i+n]=0;}}}int main()
{cin>>n;dfs(1);//从第一层开始cout<<total;return 0;
}

打表

想不到还有打表吧,哈哈哈。确实有时候很难想到

#include<iostream>
using namespace std;
int main()
{int n;cin>>n;if(n==6) //打表进行中......{puts("2 4 6 1 3 5");puts("3 6 2 5 1 4");puts("4 1 5 2 6 3");puts("4");}if(n==7){puts("1 3 5 7 2 4 6");puts("1 4 7 3 6 2 5");puts("1 5 2 6 3 7 4");puts("40");}if(n==8){puts("1 5 8 6 3 7 2 4");puts("1 6 8 3 7 4 2 5");puts("1 7 4 6 8 2 5 3");puts("92");}if(n==9){puts("1 3 6 8 2 4 9 7 5");puts("1 3 7 2 8 5 9 4 6");puts("1 3 8 6 9 2 5 7 4");puts("352");}if(n==10){puts("1 3 6 8 10 5 9 2 4 7");puts("1 3 6 9 7 10 4 2 5 8");puts("1 3 6 9 7 10 4 2 8 5");puts("724");}if(n==11){puts("1 3 5 7 9 11 2 4 6 8 10");puts("1 3 6 9 2 8 11 4 7 5 10");puts("1 3 7 9 4 2 10 6 11 5 8");puts("2680");}if(n==12){puts("1 3 5 8 10 12 6 11 2 7 9 4");puts("1 3 5 10 8 11 2 12 6 9 7 4");puts("1 3 5 10 8 11 2 12 7 9 4 6");puts("14200");}if(n==13){puts("1 3 5 2 9 12 10 13 4 6 8 11 7");puts("1 3 5 7 9 11 13 2 4 6 8 10 12");puts("1 3 5 7 12 10 13 6 4 2 8 11 9");puts("73712");}return 0;
}

后话

额外测试用例

样例输入 #2

13

样例输出 #2

1 3 5 2 9 12 10 13 4 6 8 11 7
1 3 5 7 9 11 13 2 4 6 8 10 12
1 3 5 7 12 10 13 6 4 2 8 11 9
73712

王婆卖瓜

感觉有收获或者想跟上我的进度刷题的,可以点个关注,或者点赞收藏评论都可以!

题目来源

USACO Training Section 1.5
洛谷链接

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

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

相关文章

微机原理_2

一、单项选择题(本大题共15小题,每小题3分,共45分。在每小题给出的四个备选项中,选出一个正确的答案&#xff0c;请将选定的答案填涂在答题纸的相应位置上。&#xff09; 下列数中最大的数为&#xff08;&#xff09; A. 10010101B B. (126)8 C. 96H D. 100 CPU 执行 OUT 60H,…

西门子(Siemens)仿真PLC启动报错处理

目录 一、背景&#xff1a; 二、卸载软件 三、安装软件 三、启动软件 四、下载PORTAL项目 五、测试 一、背景&#xff1a; 在启动S7-PLCSIM Advanced V3.0仿真PLC时报错&#xff0c;报错信息为&#xff1a;>>Siemens PLCSIM Virtual Switch<<is misconfigu…

Ubuntu 23.10 服务器版本 ifconfig 查不到网卡 ip(已解决)

文章目录 1、问题描述2、 解决方案 1、问题描述 服务器&#xff1a;ubuntu 23.10 经常会遇到虚拟机添加仅主机网卡后&#xff0c;通过 ifconfig 无法获取其网卡 ip 2、 解决方案 修改网卡配置文件&#xff1a; # 进入网卡配置文件目录 cd /etc/netplan # 备份原始文件 cp …

ArgoWorkflow教程(一)---DevOps 另一选择?云原生 CICD: ArgoWorkflow 初体验

来自&#xff1a;探索云原生 https://www.lixueduan.com 原文&#xff1a;https://www.lixueduan.com/posts/devops/argo-workflow/01-deploy-argo-workflows/ 本文主要记录了如何在 k8s 上快速部署云原生的工作流引擎 ArgoWorkflow。 ArgoWorkflow 是什么 Argo Workflows 是…

网络安全如何自学?

1.网络安全是什么 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 2.网络安全市场 一、是市场需求量高&#xff1b; 二、则是发展相对成熟…

Android设计模式--装饰模式

千淘万漉虽辛苦&#xff0c;吹尽黄沙始到金 一&#xff0c;定义 动态地给一个对象添加一些额外的职责。就增加功能来说&#xff0c;装饰模式相比生成子类更为灵活。 装饰模式也叫包装模式&#xff0c;结构型设计模式之一&#xff0c;其使用一种对客户端透明的方式来动态地扩展…

<JavaEE> 什么是线程(Thread)?进程和线程有什么区别?

目录 一、线程&#xff08;Thread&#xff09;的概念 二、线程存在的意义 2.1 并发编程 2.2 比进程更“轻量” 三、使用线程时应该注意 四、进程和线程的区别 五、Java中的线程和操作系统中的线程是不同的概念 六、多线程编程 一、线程&#xff08;Thread&#xff09;的…

图神经网络的数学原理总结

图深度学习(Graph Deep Learning) 多年来一直在加速发展。许多现实生活问题使GDL成为万能工具&#xff1a;在社交媒体、药物发现、芯片植入、预测、生物信息学等方面都显示出了很大的前景。 本文将流行的图神经网络及其数学细微差别的进行详细的梳理和解释&#xff0c;图深度学…

Linux中flask项目开启https访问

1.下载阿里云免费证书 2.项目添加https配置 3.服务器开启https访问 3.1 重新安装OpenSSL 3.2.重新安装Python 上一次已经讲过Linux安装部署Python: Linux安装Python3.10与部署flask项目实战详细记录,今天记录一下Python项目如何支持https访问…

性能相关的闪存特性

一、多Plane操作 上章提到若干个Plane组成Die或者叫LUN,即一个Die上有多个Plane 每次进行写操作时&#xff0c;控制器先将数据写入页缓存中&#xff0c;等同一个Die上另一个Plane也写数据的时候&#xff0c;再同时写入&#xff0c;原来单独操作一个Plane的时间变成了可以同时做…

Springmvc实现增删改差

一、包结构 二、各层代码 (1)数据User public class User {private Integer id;private String userName;private String note;public User() {super();}public User(Integer i, String userName, String note) {super();this.id i;this.userName userName;this.note note;…

Qt实现自定义IP地址输入控件(百分百还原Windows 10网络地址输入框)

在开发网络相关的程序时,我们经常需要输入IP地址,例如源地址和目标地址。Qt提供了一些基础的控件,如QLineEdit,但是它们并不能满足我们对IP地址输入的要求,例如限制输入的格式、自动跳转到下一个输入框、处理回车和退格键等。因此,我们需要自己编写一个自定义的IP地址输入…

【赠书第7期】从零基础到精通Flutter开发

文章目录 前言 1 安装Flutter和Dart 2 了解Flutter的基础概念 2.1 Widget 2.2 MaterialApp和Scaffold 2.3 Hot Reload 3 编写你的第一个Flutter应用 3.1 创建一个Flutter项目 3.2 修改默认页面 3.3 添加交互 4 深入学习Flutter高级特性 4.1 路由和导航 4.2 状态管…

python之TCP的网络应用程序开发

文章目录 版权声明python3编码转换socket类的使用创建Socket对象Socket对象常用方法和参数使用示例服务器端代码客户端代码 TCP客户端程序开发流程TCP服务端程序开发流程TCP网络应用程序注意点socket之send和recv原理剖析send原理剖析recv原理剖析send和recv原理剖析图 多任务版…

在两个java项目中实现Redis的发布订阅模式

如何在两个java项目中实现Redis的发布订阅模式&#xff1f; 1. Redis简介2. 发布订阅模式介绍3. 实现思路4. 代码实现及详细解释4.1. RedisUtil4.2. Publisher4.3. Subscriber4.4. 运行程序 目录&#xff1a; Redis简介发布订阅模式介绍实现思路代码实现及详细解释 1. Redis简…

HTB Napper WriteUp

Napper 2023年11月12日 14:58:35User Nmap ➜ Napper nmap -sCV -A -p- 10.10.11.240 --min-rate 10000 Starting Nmap 7.80 ( https://nmap.org ) at 2023-11-12 13:58 CST Nmap scan report for app.napper.htb (10.10.11.240) Host is up (0.15s latency). Not shown: …

适用于电脑的5个免费文件恢复软件分享

适用于电脑的最佳免费文件恢复软件 任何计算机用户都可能经历过丢失重要文件的恐惧。重要数据的丢失可能会令人不安和沮丧&#xff0c;无论是由于不小心删除、计算机故障还是硬盘格式化造成的。幸运的是&#xff0c;在数字时代&#xff0c;您可以使用值得信赖的解决方案检索这些…

好工具|datamap,一个好用的地图可视化Excel插件,在Excel中实现地理编码、拾取坐标

在做VRP相关研究的时候&#xff0c;需要对地图数据做很多处理&#xff0c;比如地理编码&#xff0c;根据“重庆市沙坪坝区沙正街174号”这样的一个文本地址知道他的经纬度&#xff1b;再比如绘制一些散点图&#xff0c;根据某个位置的经纬度在地图上把它标注出来。还有有的时候…

vue + docxtemplater 导出 word 文档

一、痛点 word 导出 这种功能其实之前都是后端实现的&#xff0c;但最近有个项目没得后端。所以研究下前端导出。 ps&#xff1a; 前端还可以导出 pdf&#xff0c;但是其分页问题需要话精力去计算才可能实现&#xff0c;并且都不是很完善。可参考之前的文章&#xff1a;利用 h…

JavaScript框架 Angular、React、Vue.js 的全栈解决方案比较

在 Web 开发领域&#xff0c;JavaScript 提供大量技术栈可供选择。其中最典型的三套组合&#xff0c;分别是 MERN、MEAN 和 MEVN。前端框架&#xff08;React、Angular 和 Vue&#xff09;进行简化比较。 MERN 技术栈详解 MERN 技术栈包含四大具体组件&#xff1a; MongoDB&am…