国际象棋 α 皇后问题

活动地址:CSDN21天学习挑战赛

----------文章底部代码分享

一、题目

标题:国际象棋 α 皇后问题

在 α × α 格的国际象棋上摆放 α 个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

二、解题

2.1 思路分析

  1. 将第一个皇后放在第一行第一列的格子中;
  2. 将第二个皇后放置在第二行第一列的格子中,然后进行判断,如果两个皇后满足不在同一行或同一列以及同一根斜线上的条件,则代表当前位置的格子可以放置一个皇后,这时即可再去寻找第三个皇后的位置,如果两个皇后所处位置不满足条件,那么皇后的列数就要后移一位继续判断,还不满足就再次后移直至满足条件或者证明当前行无法满足条件为止;
  3. 当第一个至第 α 个皇后都已经放置好位置时(即 α 个皇后的位置皆不冲突时)就表示当前情况是皇后问题的一种摆法;
  4. 得到了一个正确的解后,将其记录并开始回溯到上一个皇后的位置找另外的解法,如果找到了就再次寻找下一个皇后可放置的位置,如果找不到则再退回一层 …… ……;
  5. 当第一个皇后放在第一行第一列的情况全部找到后就对第一行第二列 、第三列 、……、第 α 列的情况进行寻找,直至找到所有可能;

2.2

  • 进入写代码阶段,第一步我们先创建一个数组用于保存皇后的位置,定义一个变量保存行列数,定义一个变量保存方案数;

(这里可能会有人不明白为什么是建立一个一维数组而不是二维数组,原因很简单,因为皇后的数量是跟行列数为一比一的关系,也就是说每一行都只能有一个皇后,使用一维数组保存的是皇后所处位置的列下标,而每个一维数组的下标则可以表示为皇后的行下标)

图 2.1

2.3

编写一个方法将初始为 0 的坐标数传入该方法;

图 2.2

2.4

编写方法遍历每一个位置,假定其为皇后正确坐标并由此进入递归计算下一行皇后的位置;

图 2.3

2.5

  • 在进入下一个坐标的递归之前,增加一个方法对当前坐标是否符合条件的判断,如果符合则进入递归寻找下一个行皇后的位置,如果不符合则继续遍历下一个列坐标;

  • 对坐标是否合法的判断很简单,无非是判断是否和前面所有的皇后处于同一行或同一列以及同一斜线;

  • 因为我们只让每一行存在一个皇后,故不需要判断是否存在同一行的情况;

  • 因为我们设置的数组是存放皇后的列坐标,所以需要遍历一遍查找是否有相同的情况,如果有代表发生冲突返回 false ,反之则继续下一轮的判断(要跟所有的皇后都没冲突才能返回 true);

  • 此外还要判断是否在同一条斜线上,因为同一对角线上的两个元素,它们的行坐标之差等于列坐标之差,所以我们可以把皇后位置的行坐标(皇后的行坐标就是在当前数组的位置)相减求得差值再与列坐标(皇后的列坐标就是存储的数值)的差值进行比较,如果相等则代表有冲突需要返回 false ,反之则进行下一轮判断;(因为计算机计算差值的时候并不一定会用大数减去小数,故要取绝对值)

图 2.4

2.6

在寻找皇后列下标的方法内增加一个判断,用于判断是否已经找完所有的皇后的列下标,如果找到了所有的皇后位置就将计数器进行自增记录摆法数,然后再通过返回进行回溯寻找另外的方法;如果判断并未找到所有的皇后位置则再次进入遍历;

图 2.5

2.7

最后在主方法输出方案数即完成了该题;

图 2.6

2.8

最后补充一个检查方法,该检查方法就是在每一次得到解决方案的时候将其打印出来;

  1. 打印的时候为了更加直观需要建立一个二维数组;
  2. 然后将每一行的皇后位置标记为 1 ;(之前有提过 queen 数组存储的是列坐标)
  3. 再通过枚举将该数组打印出来;

图 2.7

2.9

为避免方阵太多影响视觉,这里就只打印一个 4 x 4 的情况展示;

图 2.8

三、代码分享

import java.util.Scanner;public class test {static int[] queen;static int max, count = 0;public static void main(String[] args) {Scanner sc = new Scanner( System.in );max = sc.nextInt();queen = new int[max];Queen( 0 );System.out.println(count);}//打印方法public static void print(){int[][] arr = new int[max][max];for (int i = 0; i < max; i++) {arr[i][queen[i]] = 1;}for (int i = 0; i < max; i++) {for (int j = 0; j < max; j++) {System.out.print( arr[i][j] + "\t");}System.out.println();}System.out.println();}//寻找列坐标的方法public static void Queen( int x ){if ( x == max ){count++;print();return;}for (int i = 0; i < max; i++) {queen[x] = i;if ( collide(x) ){Queen( x + 1);}}}//检查是否存在冲突的方法public static boolean collide( int x ){for (int i = 0; i < x; i++) {if ( queen[i] == queen[x] || Math.abs(x - i) == Math.abs(queen[x] - queen[i]) ){return false;}}return true;}
}

JAVA基础算法(6)----- 国际象棋 α 皇后问题相关推荐

  1. java基础算法题(入门题与简单题)

    题目来自lintcode,答案来自九章算术,将自己在lintcode上训练的一些简单算法题贴出来,作为知识的总结与整理.便于查看复习. 第一部分(入门级别,只做了开放的部分,大部分需要收费的VIP才有 ...

  2. Java基础算法题(01):判断101-200之间有多少个素数,并输出所有素数。 素数又叫质数,就是除了1和它本身之外,再也没有整数能被它整除的数。也就是素数只有两个因子。

    查看所有50道基础算法题请看: Java的50道基础算法题 import java.util.ArrayList; import java.util.List; public class Detect ...

  3. Java基础算法题(02):古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?

    查看所有50道基础算法题请看: Java的50道基础算法题 递归的方法 package Demo02Rabbits; import java.util.Scanner; public class Ra ...

  4. Java基础算法题(07):输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。

    查看所有50道基础算法题请看: Java的50道基础算法题 package Demo07Character_Count; import java.util.Scanner; public class ...

  5. Java基础算法题(18):两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程序找出三

    查看所有50道基础算法题请看: Java的50道基础算法题 两个乒乓球队进行比赛,各出三人.甲队为a,b,c三人,乙队为x,y,z三人.已抽签决定比赛名单.有人向队员打听比赛的名单.a说他不和x比,c ...

  6. java 基础算法教程ppt,基础排序算法(附加java实现)

    七种最基本的排序算法:(面试必会!) 冒泡排序: 最基础的排序算法,从数列最前端开始,两两比较,如果前一个数比后一个数大,那么两个数就交换位置,经过一轮遍历之后,最大的数就到了数列的最后一个位置上,再 ...

  7. Java基础算法50题(一)

    文章目录 1.有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 2.判断101-200之间有多少个素数,并输出所有素 ...

  8. 50道JAVA基础算法编程题【内含分析、程序答案】【建议收藏】【建议收藏】【建议收藏】

    非常基础的题目,但是想学好Java它真的是基础,基础有多重要我就不再废话,重要的事情说三遍[建议收藏][建议收藏][建议收藏]. [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一 ...

  9. JAVA基础算法练习(5):行星碰撞

     ------文章底部代码分享 一.题目 标题:行星碰撞 给定一个整数数组 asteroids,表示在同一行的行星.对于数组中的每一个元素,其绝对值表示行星的大小,正负表示行星的移动方向(正表示向右移 ...

  10. Java基础算法50题(二)

    文章目录 26.请输入星期几的第一个字母来判断一下是星期几,如果第一个字母一样,则继续判断第二个字母. 27.求100之内的素数. 28.对10个数进行排序. 29.求一个3*3矩阵对角线元素之和. ...

最新文章

  1. Centos 7.4 中http-2.4 的基本实现和 https 的实现
  2. python实现syn半扫描_python 使用raw socket进行TCP SYN扫描实例
  3. 阿里新财报霸道惨了!菜鸟加速全球72小时必达,世界都沸腾!
  4. linux管理磁盘和文件系统
  5. 【运维】linux硬盘空间不足,扩容硬盘,挂载目录,并永久挂载
  6. Java里的数组介绍
  7. java复用类_java复用类
  8. 《Spark核心技术与高级应用》——3.2节构建Spark的开发环境
  9. 从汇编来看i++与++i
  10. python制作日历并保存成excel_利用Python自动化生成逼格高的日历!简单又实用
  11. 阿里面试真题!《阿里云技术面试红宝书》!赶紧保存下载!
  12. 安卓kali安装mysql_超详细安卓手机安装kali教程(root篇)
  13. Hexo添加可控制网易云音乐播放器
  14. 新浪短网址api接口——5个可生成新浪t.cn短链的在线工具网站评测
  15. 计算反转录转座子插入时间二:提取成对LTRs序列
  16. 什么叫黑名单?黑名单还能贷款吗?
  17. linux--设置屏幕的锁屏时间
  18. html圆角边框背景颜色,CSS之圆角边框渐变的实现
  19. 第18章_Django入门——【3.创建网页主页】与【4.创建网页其他页面】的比萨店作业
  20. 从外包到互联网,加油,打工人!

热门文章

  1. IE11 js导出excel提示Automation 服务器不能创建对象
  2. 从红牛案看商业伦理和社会公义中的众生相
  3. 计算机设置从光盘启动怎么办,[光盘启动]BIOS设置从光盘光驱启动教程
  4. css样式之导航条(nav)
  5. 标识符的命名规则及命名规范
  6. 网页标题前面的logo怎么设置
  7. excel单元格的引用
  8. 宝塔面板强制绑定手机号码解决办法
  9. 用拉格朗日插值法,牛顿插值和分段线性插值计算近似值
  10. 按键精灵通过句柄获取窗口坐标_按键精灵9 得到鼠标指向的窗口句柄