[USACO1.5] 八皇后 Checker Challenge 题解

news/2024/11/14 20:26:42/文章来源:https://www.cnblogs.com/Atserckcn/p/18331659

[USACO1.5] 八皇后 Checker Challenge

题目描述

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

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

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

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

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

输入格式

一行一个正整数 \(n\),表示棋盘是 \(n \times 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\%\) 的数据,\(6 \le n \le 13\)

题目翻译来自NOCOW。

USACO Training Section 1.5

(一)读懂题目

(Who) 关键词

6×6棋盘
六个棋子
每行、每列
每条对角线
只有一个

(What) 关键词之间关键联系:

满足每行每列每个对角线只有一个棋子的棋局就是一种解法

(How) 思路:

(1)

分析:第一反应使用深度优先搜索去做,枚举每一行,对本次摆放的棋子的每一列和每一个对角线都标上记号

(2)

分析:我们可以运用标记数组,bool类型来进行标记

(3)

分析:重要的是对角线的标记问题,但经过观察可以发现,对角线不是i+j相等就是i-j+8相等,所以可以利用这个特性来进行标记

(二)分析时间+空间复杂度

时间复杂度:O(n)
空间复杂度:O(n)

(三)代码实现

#include<iostream>
#include<cstdio>
using namespace std;
int ans,n;//ans是用来记录输出次数,题目只要求输出3次 
int a[15];//每一行 
bool b[15],c[40],d[40];//标记数组,b数组标记那一列,c和d数组标记对角线 
void print()//打印函数 
{for(int j=1;j<=n;j++){printf("%d ",a[j]);}puts("");return;
}
void dfs(int i)//重点:深搜dfs 
{if(i>n)//如果一种情况成立(i已经遍历完每一列所有位置) {ans++;//记录+1 if(ans<=3)//如果<=3才输出,否则就是+1而已 {print();}return;}for(int j=1;j<=n;j++)//枚举每一列 {if(!b[j]&&!c[i+j]&&!d[i-j+n])//如果这个点没有被其他皇后给攻击到 {//标记ing …… b[j]=true;c[i+j]=true;d[i-j+n]=true;a[i]=j;dfs(i+1);//继续深搜//取消标记,回溯ing…… b[j]=false;c[i+j]=false;d[i-j+n]=false;}}return;
}
int main(){scanf("%d",&n);dfs(1);//记得从1开始 printf("%d\n",ans);return 0;
}

(四)总结反思

本题就是著名的八皇后问题,最初由国际西洋棋棋手马克斯·贝瑟尔于1848年提出的问题,是回溯算法的典型案例。
然后就是被许多人又改成了许多版本(N皇后、K皇后、皇后游戏、还是N皇后)……
呃,正事——
本题考察的是我们对与搜索的掌握,但对于本题而言,深搜dfs的回溯还是更适合枚举方案的
所以最后也是运用了dfs进行作答
AC~# 题目(著名的八皇后问题):

[USACO1.5] 八皇后 Checker Challenge

题目描述

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

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

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

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

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

输入格式

一行一个正整数 \(n\),表示棋盘是 \(n \times 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\%\) 的数据,\(6 \le n \le 13\)

题目翻译来自NOCOW。

USACO Training Section 1.5

(一)读懂题目

(Who) 关键词

6×6棋盘
六个棋子
每行、每列
每条对角线
只有一个

(What) 关键词之间关键联系:

满足每行每列每个对角线只有一个棋子的棋局就是一种解法

(How) 思路:

(1)

分析:第一反应使用深度优先搜索去做,枚举每一行,对本次摆放的棋子的每一列和每一个对角线都标上记号

(2)

分析:我们可以运用标记数组,bool类型来进行标记

(3)

分析:重要的是对角线的标记问题,但经过观察可以发现,对角线不是i+j相等就是i-j+8相等,所以可以利用这个特性来进行标记

(二)分析时间+空间复杂度

时间复杂度:O(n)
空间复杂度:O(n)

(三)代码实现

#include<iostream>
#include<cstdio>
using namespace std;
int ans,n;//ans是用来记录输出次数,题目只要求输出3次 
int a[15];//每一行 
bool b[15],c[40],d[40];//标记数组,b数组标记那一列,c和d数组标记对角线 
void print()//打印函数 
{for(int j=1;j<=n;j++){printf("%d ",a[j]);}puts("");return;
}
void dfs(int i)//重点:深搜dfs 
{if(i>n)//如果一种情况成立(i已经遍历完每一列所有位置) {ans++;//记录+1 if(ans<=3)//如果<=3才输出,否则就是+1而已 {print();}return;}for(int j=1;j<=n;j++)//枚举每一列 {if(!b[j]&&!c[i+j]&&!d[i-j+n])//如果这个点没有被其他皇后给攻击到 {//标记ing …… b[j]=true;c[i+j]=true;d[i-j+n]=true;a[i]=j;dfs(i+1);//继续深搜//取消标记,回溯ing…… b[j]=false;c[i+j]=false;d[i-j+n]=false;}}return;
}
int main(){scanf("%d",&n);dfs(1);//记得从1开始 printf("%d\n",ans);return 0;
}

(四)总结反思

本题就是著名的八皇后问题,最初由国际西洋棋棋手马克斯·贝瑟尔于1848年提出的问题,是回溯算法的典型案例。
然后就是被许多人又改成了许多版本(N皇后、K皇后、皇后游戏、还是N皇后)……
呃,正事——
本题考察的是我们对与搜索的掌握,但对于本题而言,深搜dfs的回溯还是更适合枚举方案的
所以最后也是运用了dfs进行作答
AC~

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

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

相关文章

HTTP 缓存

避免发送 HTTP 请求的方法就是通过缓存技术,HTTP 设计者早在之前就考虑到了这点,因此 HTTP 协议的头部有不少是针对缓存的字段。HTTP 缓存有两种实现方式,分别是强制缓存和协商缓存。 强制缓存 只要浏览器判断缓存没有过期,则直接使用浏览器的本地缓存,决定是否使用缓存的…

记一次WPS目录多一级,更新目录之后多出一级没出现在目录中的解决方案

背景:拿着别人写的文章做模板,别人只有三级目录,我多了一级,即我有四级目录 文章写完之后,更新目录,第四级标题没有展示 解决办法:选择引用,目录,自定义目录然后在显示级别处增加一个(点击向上箭头)

JDK工具

jps(Java Process Status):查看正在运行的Java进程 jstat(JVM Statistics Monitoring Tool):查看 JVM 的统计信息 jstat -gc 24388 输出字段:S0C、S1C:Survivor 0 和 Survivor 1 区域的当前容量(KB)S0U、S1U:Survivor 0 和 Survivor 1 区域的已使用空间(KB)EC:Eden…

远程桌面文件传输异常或者取消传输后一直显示正在取消

环境: Window Servers 2008 R2 摘要说明: 本篇文章主要讲述当应用远程桌面进行文件传输时,若因网络等导致进程中断,再次传输时则不能进行文件传输;或者传输时取消传输,然后一直显示正在取消。此时可以通过重启window的rdpclip.exe进程来解决此问题 步骤 1.关闭rdpclip.ex…

机器学习:详解是否要使用端到端的深度学习?(Whether to use end-to-end learning?)

详解是否要使用端到端的深度学习? 假设正在搭建一个机器学习系统,要决定是否使用端对端方法,来看看端到端深度学习的一些优缺点,这样就可以根据一些准则,判断的应用程序是否有希望使用端到端方法。这里是应用端到端学习的一些好处,首先端到端学习真的只是让数据说话。所以…

数独解密小程序

本程序为C#控制台(.Net Framework 目标框架)使用方法在data.csv中填好已有的数据,需要解密的数据空着不填。using System; using System.Diagnostics; using System.IO;namespace 数独解密 {class Program{static void Main(){// 动态确定数独板的大小int size = GetBoardSiz…

数据库索引的简单分类

数据库的索引可以简单的分为四类:主键索引。针对表的主键所创建的索引,这种索引是默认自动创建的,而且只能有一个。唯一索引。避免表中某列的值重复,可以有多个唯一索引,在为某字段限定唯一约束时,会自动创建一个唯一索引。常规索引。一般的用于快速定位检索数据的索引,…

Linux环境下如何升级openssl?

访问官网地址下载最新版本 下载所需版本可访问:历史版本 1.下载OpenSSL源码包 wget https://www.openssl.org/source/old/3.3/openssl-3.3.0.tar.gz 安装必要的依赖 yum install -y openssl-devel perl gcc gcc-c++ zlib 解压源码包 tar -zxvf openssl-3.3.0.tar.gz 进入源码目…

适合证券公司的跨网传输解决方案,了解一下!

证券公司由于其业务特性,涉及大量的敏感财务数据和交易信息,因此通常会在内部实施网络隔离措施。目的是为了保护数据免受未授权访问和网络攻击,确保数据的安全性和保密性,因此急需寻找安全可靠的跨网传输解决方案,实现不同网间数据的安全传输。以下是证券公司可能会采取的…

创建android项目

启动Android Studio,点击New Project因为要使用java语言,模板选择1或2配置如下

如何智能便捷、自动化地进行文件数据采集?

文件数据采集是指从各种源头和渠道收集、整理、清洗、分析和挖掘数据的过程。它是大数据应用的基础,为企业提供全面的决策支持和业务价值。文件数据采集对于不同行业都至关重要,通过有效的文件数据采集,企业可以更好地了解市场动态、优化服务和产品,以及提高运营效率。金融…

2024.7.25模拟赛7

模拟赛 疯狂补题解/改题中。。。 T1 [Permutations & Primes] (未找到)构造一个 \(1-n\) 的序列,使所有区间中 \(mex\) 为质数的最多。感觉题不是很好。结论是:\(1\) 放中间,\(2,3\) 放两边。 打标找规律,感性证明也挺显然的。no codeT2 Spread of Information 首先看道…