在学习2n皇后之前,我们应该认识一下n皇后问题:

在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
输入样例:
1
8
5
0
输出样例:
1
92
10

可以这么理解,以4皇后为例子:

现在剩下的问题是通过一些必要的操作使得这个算法的运算效率变高,这就是剪枝;

可以这样认为,设起始第一行第一列放皇后并设其坐标是(0,0),设放皇后的坐标为(i,j),为了避免重复,新皇后的坐标是(r,c),

可以看到:为了避免同列j!=c;

然后同行我们可以不用比较(因为我们是遵循着每一行只放一个皇后的原则摆放);

假设从放皇后的坐标到新皇后的坐标斜着走a步,那有新皇后坐标相对于皇后坐标来讲的话就有左上(i-r,j-c),左下(i-a,j+a),右下(i+a,j+a),右上(i+a,j-a),无论如何,都是|i-r|=|j-c|;

那为了满足题目要求就有|i-r|!=|j-c|;

题目就明确了,代码如下:

#include<bits/stdc++.h>
using namespace std;
int col[12]={0}; //col数组用于存放第i行第col[i]列放置皇后。
int n,tot = 0; //设置全局变量,即可不用投值,直接调用
bool check(int r,int c){ //判断新皇后是否和放好的皇后发生冲突。
for(int i=0;i<r;i++){
//这里不需要判断是否同行,因为我们设置的每行只投放一个皇后,所以不需要判断,只判断是否同列或者同斜线即可。
if((col[i]==c)||(abs(col[i]-c)==abs(i-r)))return false;
}
return true;
}
void dfs(int r){
if(r==n){ //因为从0开始,当行数r达到n时,表示已经完成了
tot++;
return ;
}
for(int c=0;c<n;c++){
if(check(r,c)){ //判断是否可以放置,可以便放置,否则剪枝。
col[r]=c;
dfs(r+1); //继续放置下一行的新皇后
}
}
}
int main(){
int ans[12]={0};
for(n=0;n<=10;n++){ //对n皇后进行打表,然后结果存入ans数组
memset(col,0,sizeof(col)); //每次要进行初始化
tot=0;
dfs(0); //DFS
ans[n]=tot; //存放
}
while(cin >> n){
if(n==0)return 0;
cout << ans[n] << endl;
}
return 0;
}

并且附上一个讲的很好的视频链接:https://www.bilibili.com/video/BV1bK4y1n7iq?spm_id_from=333.999.0.0

接下来就是2n皇后问题了,大体思路和n皇后问题差不多了,不同之处是需要判断能不能放皇后,那我们可以如下解决:

在放完了黑皇后(先放黑)在处理白皇后,其中如果没放完的话判断能不能放皇后这样一个问题,然后对于白皇后我们除了判断能不能放皇后的同时也要判断那个位置是不是被黑皇后占了

代码如下:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 10;
int n;
int mapqueen[maxn][maxn]; //能不能放皇后
int whqueen[maxn]={0}; //白皇后位置
int blqueen[maxn]={0}; //黑皇后位置
int ans;
bool checkbl(int step,int c)
{
for(int i=1;i<step;i++)
{
if(blqueen[i]==c||(abs(blqueen[i]-c)==abs(i-step)))
return false;
}
return true;
}
bool checkwh(int step,int c)
{
for(int i=1;i<step;i++)
{
if(whqueen[i]==c||(abs(whqueen[i]-c)==abs(i-step)))
return false;
}
return true;
}
void dfs_white(int step)
{
if(step==n+1)
{
ans++;
}
for(int c=1;c<=n;c++)
{
if(blqueen[step]==c)
continue;
if(mapqueen[step][c]==0)
continue;
whqueen[step]=c;
if(checkwh(step,c))
{
dfs_white(step+1);
}
}
}
void dfs_black(int step)
{
if(step==n+1)
{
dfs_white(1);
}
for(int c=1;c<=n;c++)
{
if(mapqueen[step][c]==0)//第step行第i列是否放了皇后的条件
continue;
blqueen[step]=c;//在第step行第i列放黑皇后
if(checkbl(step,c))
{
dfs_black(step+1);//进入下一层
}
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&mapqueen[i][j]);
}
}
dfs_black(1);//从第一行开始搜黑皇后
printf("%d\n",ans);
return 0;
}

蓝桥杯试题 基础练习 2n皇后问题以及n皇后问题的更多相关文章

  1. Java实现 蓝桥杯VIP 基础练习 2n皇后问题

    基础练习 2n皇后问题 时间限制:1.0s 内存限制:512.0MB 问题描述 给定一个n*n的棋盘,棋盘中有一些位置不能放皇后.现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一 ...

  2. 【算法】蓝桥杯 试题 基础练习 Huffuman树

    资源限制 时间限制:1.0s   内存限制:512.0MB 问题描述 Huffman树在编码中有着广泛的应用.在这里,我们只关心Huffman树的构造过程. 给出一列数{pi}={p0, p1, …, ...

  3. Java实现 蓝桥杯VIP 基础练习 Huffuman树

    基础练习 Huffuman树 问题描述 Huffman树在编码中有着广泛的应用.在这里,我们只关心Huffman树的构造过程. 给出一列数{pi}={p0, p1, -, pn-1},用这列数构造Hu ...

  4. Java实现 蓝桥杯VIP 基础练习 时间转换

    问题描述 给定一个以秒为单位的时间t,要求用"h️s" 的格式来表示这个时间.H表示时间,M表示分钟,而s表示秒,它们都是整数且没有前导的"0".例如,若t=0 ...

  5. Java实现 蓝桥杯VIP 基础练习 字符串对比

    问题描述 给定两个仅由大写字母或小写字母组成的字符串(长度介于1到10之间),它们之间的关系是以下4中情况之一: 1:两个字符串长度不等.比如 Beijing 和 Hebei 2:两个字符串不仅长度相 ...

  6. Java实现 蓝桥杯VIP 基础练习 分解质因数

    题目介绍 问题描述 求出区间[a,b]中所有整数的质因数分解. 输入格式 输入两个整数a,b. 输出格式 每行输出一个数的分解,形如k=a1a2a3-(a1<=a2<=a3-,k也是从小到 ...

  7. Java实现 蓝桥杯VIP基础练习 矩形面积交

    描述 平面上有两个矩形,它们的边平行于直角坐标系的X轴或Y轴.对于每个矩形,我们给出它的一对相对顶点的坐标,请你编程算出两个矩形的交的面积. 输入 输入仅包含两行,每行描述一个矩形. 在每行中,给出矩 ...

  8. Java实现 蓝桥杯VIP 基础练习 完美的代价

    package 蓝桥杯VIP; import java.util.Scanner; public class 完美的代价 { public static int sum = 0; public sta ...

  9. Java实现 蓝桥杯 蓝桥杯VIP 基础练习 数的读法

    问题描述 当输入12 3456 7009时,会给出相应的念法: 十二亿三千四百五十六万七千零九 用汉语拼音表示为 shi er yi san qian si bai wu shi liu wan qi ...

随机推荐

  1. 「算法笔记」CRT 与 exCRT

    一.扩展欧几里得 求解方程 \(ax+by=\gcd(a,b)\). int exgcd(int a,int b,int &x,int &y){ if(!b) return x=1,y ...

  2. JSON.parse 和 JSON.stringify 详解

    JSON格式,(简写JavaScript Object Notation),是一种用于数据交换的文本格式,书写简单. 基于JavaScript原生语法,能够序列化对象.数组.数值.字符串.布尔值和 n ...

  3. [黑科技]pb_ds库(G++)

    一.hash(速度快的恐怖).http://codevs.cn/problem/1230/ 1 #include<stdio.h> 2 #include<ext/pb_ds/asso ...

  4. Java网络编程Demo,使用TCP 实现简单群聊功能GroupchatSimple,多个客户端输入消息,显示在服务端的控制台

    效果: 服务端 客户端 实现代码: 服务端 import java.io.IOException; import java.net.ServerSocket; import java.net.Sock ...

  5. Oracle中的基本数据类型

    一.Oracle 基本数据类型 1.字符数据类型 CHAR:存储固定长度的字符串,如果没有指定长度,默认为1个字节,如果数据长度没有达到指定的长度,则通过填充空格的方式来使其达到定义的长度(CHAR类 ...

  6. Kafka基础教程(三):C#使用Kafka消息队列

    接上篇Kafka的安装,我安装的Kafka集群地址:192.168.209.133:9092,192.168.209.134:9092,192.168.209.135:9092,所以这里直接使用这个集 ...

  7. 基于node和npm的命令行工具——tive-cli

    前端开发过程中经常会用到各种各样的脚手架工具.npm全局工具包等命令行工具,如:Vue脚手架@vue/cli.React脚手架create-react-app.node进程守卫工具pm2.本地静态服务 ...

  8. Linux下如何部署FTP服务器

    FTP 是 File Transfer Protocol 的缩写,即文件传输协议,它通过网络在服务器和客户端之间传输文件,现在已经成为一种广泛使用的标准工具 vsftpd 是 very secure ...

  9. Flask + UnitTest(十五)

    被测试视图 # coding:utf-8 from flask import Flask, request, jsonify app = Flask(__name__) @app.route(&quo ...

  10. celery起动,运行有警告

    运行命令 :  celery worker -A task_log -l info: 有如下警告 2019-12-22 22:42:50,215: WARNING/MainProcess] /root ...