(1)问题描述

  在 n × n 格的棋盘上放置彼此不受攻击的 n 个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n 后问题等价于在 n × n 的棋盘上放置 n 个皇后,任何 2 个皇后不放在同一行或同一列或同一斜线上。

  

(2)算法描述

  a. 将第一个皇后放置在第一行的第一个空格里;

  b. 对于第二行,从第一个空格开始寻找不与第一行的皇后冲突的空格。找到的第一个不冲突的空格是第2个;

  c. 对于第三行,这时已经找不到与之前放置的两个皇后不冲突的空格了。把当前行恢复初始状态,返回到上一行;

  d. 在当前行皇后所占的空格之后寻找一个不与之前皇后冲突的位置。有两种情况,如果找到了则把当前行的皇后移动到该位置,然后处理下一行。如果直到最后当前行的最后一个空格也没有找合适的位置,则把当前行恢复初始状态,继续回溯到上一行;

  e. 把最后一个皇后成功安置在最后一行,代表找到了一种可行解。返回步骤 d ;

  f. 当需要回溯到第 0 行的时候代表已经找遍了所有可能的可行解。

(3)算法代码

public class NQueen {

    /**
* 皇后数量
*/
private static Integer num; /**
* 可行解的总数
*/
private static Integer sum = 0; /**
* n 皇后当前解
*/
private static Integer[] answer; /**
* 初始化数据
*/
private static void initData() {
Scanner input = new Scanner(System.in);
System.out.println("请输入 n 皇后数量:");
num = input.nextInt(); answer = new Integer[num];
} /**
* 判断当前皇后存放是否可行
*/
private static Boolean bound(int t) {
for (int i = 0; i < t; i++) { // 判断第 t 个皇后和前面已经存放好的第 (0 ~ num -1) 个皇后之间是否存在同列同斜率
/**
* 1)Math.abs(t - i) 表示两点的纵坐标;
* 2)Math.abs(answer[t] - answer[i]) 表示两点的横坐标;
* 3)answer[t] == answer[i] 表示两个皇后是否同列;
*/
if ((Math.abs(t - i) == Math.abs(answer[t] - answer[i])) || (answer[t] == answer[i])) {
return false;
}
}
return true;
} /**
* 回溯求解 n 皇后问题
*/
private static void backtrack(int t) {
if (t == num) { // 第 n 个皇后已经填完毕,满足条件
// 输出当前可行解
Stream.of(answer).forEach(element -> System.out.print(element + " "));
System.out.println();
sum++;
return;
}
for (int j = 0; j < num; j++) { // 将第 t 个皇后依次放入 (0 ~ num - 1) 个位置进行判定
answer[t] = j; // 将第 t 个皇后放入 j 位置
if (bound(t)) { // 判断将第 t 个皇后放入 j 位置,是否符合条件
backtrack(t + 1);
}
}
} public static void main(String[] args) {
// 初始化数据
initData(); // 回溯求解 n 皇后问题
backtrack(0); System.out.println("可行性解总数: sum = " + sum);
} }

n皇后算法核心代码

(4)输入输出

请输入 n 皇后数量:
5
0 2 4 1 3
0 3 1 4 2
1 3 0 2 4
1 4 2 0 3
2 0 3 1 4
2 4 1 3 0
3 0 2 4 1
3 1 4 2 0
4 1 3 0 2
4 2 0 3 1
可行性解总数: sum = 10

(5)总结

  n 皇后问题同样提现了回溯算法的核心思想,依次深度搜索,回溯到上一层;但是不与 子集树、排序树相同,有一定的区别,每一个皇后寻找位置都是从头依次找合适的位置,直到行尾才结束,然后回溯到上一层;时间复杂度为:O(nn);

  同样希望大家能动手实践一下,画一画走一下代码流程,加深回溯算法的思想。

回溯算法 - n 皇后问题的更多相关文章

  1. 回溯算法————n皇后、素数串

    回溯就是算法是搜索算法中一种控制策略,是一个逐个试探的过程.在试探的过程中,如果遇到错误的选择,就会回到上一步继续选择下一种走法,一步一步的进行直到找到解或者证明无解为止. 如下是一个经典回溯问题n皇 ...

  2. 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,循环控制及其优化

    上两篇博客 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现 研究了递归方法实现回溯,解决N皇后问题,下面我们来 ...

  3. 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案

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

  4. 回溯算法之n皇后问题

    今天在看深度优先算法的时候,联想到DFS本质不就是一个递归回溯算法问题,只不过它是应用在图论上的.OK,写下这篇博文也是为了回顾一下回溯算法设计吧. 学习回溯算法问题,最为经典的问题我想应该就是八皇后 ...

  5. 回溯算法-C#语言解决八皇后问题的写法与优化

    结合问题说方案,首先先说问题: 八皇后问题:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. 嗯,这个问题已经被使用各种语言解 ...

  6. C语言回溯算法解决N皇后问题

    回溯算法的模型是 x++, not satisfy ? x-- : continue. 代码中x作列号,y[x]保存第x列上皇后放置的位置. #include<stdio.h> #incl ...

  7. 回溯算法 LEETCODE别人的小结 一八皇后问题

    回溯算法实际上是一个类似枚举的搜索尝试过程,主要是在搜索尝试中寻找问题的解,当发现已不满足求解条件时,就回溯返回,尝试别的路径. 回溯法是一种选优搜索法,按选优条件向前搜索,以达到目的.但是当探索到某 ...

  8. 回溯算法——解决n皇后问题

    所谓回溯(backtracking)是通过系统地搜索求解问题的方法.这种方法适用于类似于八皇后这样的问题:求得问题的一个解比较困难,但是检查一个棋局是否构成解很容易. 不多说,放上n皇后的回溯问题代码 ...

  9. JS算法之八皇后问题(回溯法)

    八皇后这个经典的算法网上有很多种思路,我学习了之后自己实现了一下,现在大概说说我的思路给大家参考一下,也算记录一下,以免以后自己忘了要重新想一遍. 八皇后问题 八皇后问题,是一个古老而著名的问题,是回 ...

随机推荐

  1. ImageMagick实现图片的旋转/翻转/裁剪(ImageMagick6.9.10)

    一,imagemagick的安装 请参见: https://www.cnblogs.com/architectforest/p/12807514.html 说明:刘宏缔的架构森林是一个专注架构的博客, ...

  2. 极简 Node.js 入门 - 5.3 静态资源服务器

    极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...

  3. JavaScript的9大排序算法详解

    一.插入排序 1.算法简介 插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法.它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入. ...

  4. mongodb 数据操作CRUD

    链接到mongo 新建超级用户 上文中我们提到mongo用户库表管理.为了方便我们先新建一个root权限的用户. db.createUser({user:'dbadmin',pwd:'123456', ...

  5. docker-compose启动consul集群

    version: '2.0' services: consul-server1: image: consul:latest hostname: "consul-server1" p ...

  6. vue-cli2.0创建项目步骤

    Vue是近两年来比较火的一个前端框架(渐进式框架吧),与reactjs和angularjs三国鼎立,我不是职业前端,做过Vue,了解了一下React,听说过Angluar.我只能这么说,我来晚了,没经 ...

  7. 基于flask的python注册到eureka

    Eureka架构中的三个核心角色: 服务注册中心 Eureka的服务端应用,提供服务注册和发现功能,就是刚刚我们建立的eureka-demo 服务提供者 提供服务的应用,可以是SpringBoot应用 ...

  8. python使用matplotlib画图,jieba分词、词云、selenuium、图片、音频、视频、文字识别、人脸识别

    一.使用matplotlib画图 关注公众号"轻松学编程"了解更多. 使用matplotlib画柱形图 import matplotlib from matplotlib impo ...

  9. mysql管理表关系

    表关系管理 关注公众号"轻松学编程"了解更多. 1.概述 ​ 表与表之间的关系可以是一对一.一对多.多对一的.通过外键把表连接起来,外键放在任意一张表都可以,通常选择由从表(相对次 ...

  10. python类的封装与继承

    封装 关注公众号"轻松学编程"了解更多. 1.概念 面向对象语言的三大特征:封装, 继承, 多态. 广义的封装: 类和函数的定义本身就是封装的体现. 狭义的封装:一个类的某些属性, ...