题目:

The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.

Given an integer n, return all distinct solutions to the n-queens puzzle.

Each solution contains a distinct board configuration of the n-queens' placement, where 'Q' and '.' both indicate a queen and an empty space respectively.

Example:

Input: 4
Output: [
[".Q..", // Solution 1
"...Q",
"Q...",
"..Q."], ["..Q.", // Solution 2
"Q...",
"...Q",
".Q.."]
]
Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above.

分析:

皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。

每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。

非常经典的问题,首先可以想到的是穷举所有皇后摆放的情况,来判断棋盘是否符合要求。但这样做肯定是会超时的。

以n=4为例,我们构建一个二维数组sta,用来标识皇后能否放置,最开始皇后可以放置再任何地方,我们从第一行开始放置皇后,根据放置的位置,我们来修改sta数组(1为不能放置,0为可以放置),将放置位置的行列以及两条对角线上的元素全部置1,之后在第二行放置皇后,并根据sta数组来判断当前位置皇后是否可以被放置,如果当前行搜索完毕后,都没有位置放置皇后,那么我们就要回到上一步放置皇后的状态,再去搜索下一个位置了。每次放置前要保存当前结果和当前判断数组(sta)以便回溯。

对于判断皇后放置的二维数组,可以换成一个列数组加上两个对角线数组来标记一个位置是否可以放置皇后,因为我们是一行一行来放置的,所以不存在某一行出现两个皇后,所以当一列放置了一个皇后时,该列标记为不可放置(col[i]=1,即第i列已经有皇后了),对角线可以对照下图:

[x,y]位置对应从左下角至右上角的对角线diag1[x+y],而对应从左上角至右下角的对角线diag2[y-x+n-1],这样每一个位置能否放置皇后判断的条件都有了,不用再使用一个棋盘大小的二维数组来标识了。

程序:

class Solution {
public:
void update(int n, vector<vector<int>> &vec, int x, int y){
for(int i = ; i < n; ++i){
vec[i][y] = ;
vec[x][i] = ;
}
int i = ,j = ;
for(i = x, j = y; i < n && j < n; ++i, ++j){
vec[i][j] = ;
}
for(i = x, j = y; i >= && j >= ; --i, --j){
vec[i][j] = ;
}
for(i = x, j = y; i < n && j >= ; ++i, --j){
vec[i][j] = ;
}
for(i = x, j = y; i >= && j < n; --i, ++j){
vec[i][j] = ;
}
return;
}
void queen(int n, int y, vector<string> &temp_res, vector<vector<int>> &sta){
if(y == n){
res.push_back(temp_res);
return;
}
for(int j = ; j < n; ++j){
if(sta[y][j] == ){
vector<string> temp2 = temp_res;
temp_res[y][j] = 'Q';
vector<vector<int>> temp = sta;
update(n, sta, y, j);
queen(n, y+, temp_res, sta);
sta = temp;
temp_res = temp2;
}
else
continue;
}
return;
}
vector<vector<string>> solveNQueens(int n) {
vector<string> temp_res(n, string(n, '.'));
vector<vector<int>> sta(n, vector<int>(n,));
queen(n, , temp_res, sta);
return res;
}
private:
vector<vector<string>> res;
};
class Solution {
public:
void queen(int n, int x, vector<string> &temp_res){
if(x == n){
res.push_back(temp_res);
return;
}
for(int y = ; y < n; ++y){
if(col[y] == && diag1[x+y] == && diag2[y-x+n-] == ){
temp_res[x][y] = 'Q';
col[y] = ;
diag1[x+y] = ;
diag2[y-x+n-] = ;
queen(n, x+, temp_res);
temp_res[x][y] = '.';
col[y] = ;
diag1[x+y] = ;
diag2[y-x+n-] = ;
}
else
continue;
}
return;
}
vector<vector<string>> solveNQueens(int n) {
vector<string> temp_res(n, string(n, '.'));
col = vector<int>(n, );
diag1 = vector<int>( * n - , );
diag2 = vector<int>( * n - , );
queen(n, , temp_res);
return res;
}
private:
vector<vector<string>> res;
vector<int> col;
vector<int> diag1;
vector<int> diag2;
};

LeetCode 51. N-QueensN皇后 (C++)(八皇后问题)的更多相关文章

  1. LeetCode 回溯法 别人的小结 八皇后 递归

    #include <iostream> #include <algorithm> #include <iterator> #include <vector&g ...

  2. USACO 1.5.4 Checker Challenge跳棋的挑战(回溯法求解N皇后问题+八皇后问题说明)

    Description 检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行,每列,每条对角线(包括两条主对角线的所有对角线)上都至多有一个棋子. 列号 0 1 2 3 4 5 6 ...

  3. 九度OJ 1140:八皇后 (八皇后问题)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:795 解决:494 题目描述: 会下国际象棋的人都很清楚:皇后可以在横.竖.斜线上不限步数地吃掉其他棋子.如何将8个皇后放在棋盘上(有8 * ...

  4. LeetCode 31:递归、回溯、八皇后、全排列一篇文章全讲清楚

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天我们讲的是LeetCode的31题,这是一道非常经典的问题,经常会在面试当中遇到.在今天的文章当中除了关于题目的分析和解答之外,我们还会 ...

  5. C#中八皇后问题的递归解法——N皇后

    百度测试部2015年10月份的面试题之——八皇后. 八皇后问题的介绍在此.以下是用递归思想实现八皇后-N皇后. 代码如下: using System;using System.Collections. ...

  6. 【剑指offer】八皇后问题

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/26614999 剑指offer上解决八皇后问题,没实用传统的递归或非递归回溯法,而是用了非常 ...

  7. 带你轻而易举的学习python——八皇后问题

    首先我们来看一下这个著名的八皇后问题 八皇后问题:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. 在这个问题提出之后人们又将 ...

  8. java递归求八皇后问题解法

    八皇后问题 八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处 ...

  9. 数据结构之递归Demo(走迷宫)(八皇后)(汉诺塔)

    递归 顾名思义,递归就是递归就是递归就是递归就是递归......就是递归 Google递归:

随机推荐

  1. Go micro 入门

    路由跳转 官方文档 本质上是选择不同的方式将HTTP信息合理的转发至后端处理,而不同的方式相当于不同请求的接收器,接收后再将其转发至不同的后端服务,完成整个请求的调用. micro 将请求选择不同的方 ...

  2. JAVA基础系列:反射

    1. 定义 在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这 种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. ...

  3. [NewLife.XCode]分表分库(百亿级大数据存储)

    NewLife.XCode是一个有15年历史的开源数据中间件,支持netcore/net45/net40,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量 ...

  4. Spring Boot(十二):LocalDateTime格式化处理

    Java 8之后,日期类的处理建议使用java.time包中对应的LocalDateTime, LocalDate, LocalTime类.(参考Java8新特性) 在Spring Boot中(验证版 ...

  5. vs2017 升级后无法启动 z

    Visual Studio 2017 无法启动,进程中却有devenv.exe运行的解决办法 双击Visual Studio 2017,系统没有响应,在任务管理器中却发现devenv.exe 已经在运 ...

  6. vuex 源码分析(六) 辅助函数 详解

    对于state.getter.mutation.action来说,如果每次使用的时候都用this.$store.state.this.$store.getter等引用,会比较麻烦,代码也重复和冗余,我 ...

  7. Kubernetes Pod 镜像拉取策略

    Kubernetes Pod 镜像拉取策略 官方文档:https://kubernetes.io/docs/concepts/containers/images/ • IfNotPresent:默认值 ...

  8. 通过Filebeat把日志传入到Elasticsearch

    学习的地方:配置文件中预先处理字段数据的用法 通过Filebeat把日志传入到Elasticsearch Elastic Stack被称之为ELK (Elasticsearch,Logstash an ...

  9. Linux CentOS内核升级

    1. 说明 正在使用的阿里云服务器报了几个内核漏铜,使用自带[一键修复]需要额外的支付费用,所以尝试采用升级系统内核的方式来修复漏洞. 1.1 服务器参数 操作系统:CentOS 7.4 64位 当前 ...

  10. 我脑中的JVM大全附带Java8的特性

    Java虚拟机-sun classic vm 世界上第一款商用的Java虚拟机. 只能使用纯解释器的方式来执行Java代码. Java虚拟机-ExactVM Exact Memory Manageme ...