(Java实现) N皇后问题
n皇后问题是一个以国际象棋为背景的问题:在n×n的国际象棋棋盘上放置n个皇后,使得任何一个皇后都无法直接吃掉其他的皇后,即任意两个皇后都不能处于同一条横行、纵行或斜线上。
蛮力法思想:
解决n皇后问题的思想本质上就是蛮力法,生成所有可能的摆放情况,并判断该情况是否满足要求,我们以树结构来表示解决问题的方法。以4*4的棋盘为例,第0层的根节点为空白的棋盘,第1层为只在棋盘的第一行摆放的四种不同情况,第2层是在第1层的基础上,摆放第二行的棋子,最后的叶子结点便是所有可能的完整摆放情况,共256种,但加上中途生成的不完整情况共1+4+16+64+256=340种。

回溯法思想:
回溯法其实是以蛮力法为基础,只是不需要生成所有的情况,我们可以发现,在整棵树中,有些棋盘的摆放情况在未达到叶子结点时,便已经不满足n皇后的条件了,那么我们就没有必要再去往下摆放棋子(生成下一层的结点),而是直接回到该结点的父节点,生成新的情况进行判断。通过这种方法可以减少生成完全树中的一些不必要的子树,我们称之为“剪枝”。具体实现中回溯法与蛮力法的主要区别在于判断棋盘的代码所在的位置,蛮力法在摆放完所有皇后后再判断,回溯法在每摆放好一个皇后时就进行判断。

具体实现:
根据n皇后问题的规模,创建大小为n的数组代替树结构,使其下标代表行数,内容代表列数,数组中的每个数必定位于不同的行,数组内容不同证明两个元素位于不同的列,两数下标的差的绝对值不等于两数内容的差的绝对值,表示两数不位于同一斜线上。
import java.util.Arrays;
import java.util.Scanner;
public class Nhuanghouwenti {
private static int queenNum;//皇后的个数
private static int[] hash;//下标表示i号皇后(皇后i放在第i行)value表示放的列号
private static int count = 0;//合法摆放方式的个数
public static void placeQueen(int m) {
if (m > queenNum) {//如果摆到了n+1行了,说明前n行都是不冲突的,合法的
count++;
for (int i = 1; i <=queenNum; i++) {
System.out.print(hash[i]);
}
System.out.println();
// System.out.println(Arrays.toString(hash));
//打印合法的摆放结果
// for(int i = 1; i <= queenNum; i++){
// int column = hash[i];//hash值表示皇后i所在的列号
// for(int j = 1; j <= queenNum ;j++){
// if(j!= column){
// System.out.print("* ");
// }else{
// System.out.print("Q ");
// }
// }
// System.out.println();
// }
return;
}
for (int i = 1; i <= queenNum; i++) {
//check the column is conflict with former ones or not
//if so, check the next column until find a non-conflict column
//or until the last column ,return;
if (isConfilct(m, i)) {
continue;
} else {//如果检测到第i列不冲突,是安全的,
hash[m] = i;//将皇后m放在第i列
placeQueen(m + 1);//再放皇后m+1,
//如果皇后m+1放完并返回了
//两种可能:
//1:冲突,返回了
//2.一直将所有的皇后全部放完并安全返回了
//将皇后m回溯,探索新的可能或者安全的位置
hash[m] = -1;
//其实这里没必要将m重新赋值的,因为检测到下一个
//安全位置的时候会把hash[m]覆盖掉的
//但是为了更好的体现“回溯”的思想,在这里画蛇添足了
}
}
}
/**
* 检测冲突
* @param index
* 表示行号
* @param hash 表示第i行放置皇后的列数
* 值表示列号
* @return
*/
private static boolean isConfilct(int row, int column) { //一行一个皇后,第n个皇后也代表着第n行
if(row == 1){//第1行永远不会冲突
return false;
}
//只需要保证与那些已经就位的皇后不冲突即可
for (int i = 1; i < row; i++) { //当前的行数
if (hash[i] == column || ( column - row) == (hash[i] - i) || (row - column)== (i-hash[i]) //以前行数减列数与现在的是否相等
|| (row + column) == (hash[i] + i)) {
return true;
}
}
return false;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
queenNum = sc.nextInt();
hash = new int[queenNum + 1];
for (int i = 0; i < hash.length; hash[i++] = -1);//初始化棋盘
placeQueen(1);
System.out.println(count);
}
}
(Java实现) N皇后问题的更多相关文章
- Java实现八皇后
实验题目 回溯法实现8皇后问题 实验要求 a.掌握递归回溯算法的基本思想. b.学习掌握应用面向对象通用回溯程序框架解决实际问题. 提高面向对象编程的技能. 作业描述:在8*8格的棋盘上放置 ...
- 易理解java代码8皇后问题
马上就要蓝桥杯比赛了,我这些算法还是不会,确实有点慌,今天一天早上睡到很晚不愿起床,然后才开始研究8皇后问题.这也是典型的回溯与递归问题.其实本质上和马踏棋盘问题非常类似,八皇后问题呢,就是要判断主对 ...
- java实现八皇后问题(递归和循环两种方式)
循环方式: package EightQueens; public class EightQueensNotRecursive { private static final boolean AVA ...
- 比赛组队问题 --- 递归解法 --- java代码 --- 八皇后问题
两队比赛,甲队为A.B.C3人,乙队为X.Y.Z3人.已知A不和X比,C不和X.Z比,请编程序找出3队赛手名单 采用了与八皇后问题相似的解法,代码如下: 如有疑问请链接八皇后问题的解法:http:// ...
- 2018.4.24 java实现8皇后算法
import java.util.Scanner; public class Nqueens { private boolean verify(int[] arr,int i) { // TODO A ...
- JAVA实现N皇后问题(回溯法)
package com.leetCode; /** * Follow up for N-Queens problem. Now, instead outputting board configurat ...
- n皇后2种解题思路与代码-Java与C++实现
林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主要讲了n皇后问题的解题思路,并分别用java和c++实现了过程,最后,对于算法改进 ...
- Spark案例分析
一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...
- 八皇后java算法
import java.util.Date; public class EightQueen { public static void main(String[] args) { long star ...
随机推荐
- 单向环形链表解决约瑟夫环(Josephus)问题
一.约瑟夫环问题 Josephu 问题为:设编号为1,2,- n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列,它的下一位又从1开始报数,数到m的那 ...
- [zoj 3416/hdu 3709]数位DP
题意:求从区间[L, R]内有多少个数是平衡数,平衡数是指以10进制的某一位为中心轴,左右两边的每一位到中心轴的距离乘上数位上的值的和相等.0<=L<=R<=1e18 思路:由于任何 ...
- Nginx下的location,upstream,rewrite 和 proxy_pass使用总计大全
一 . location: 顾名思义-->地址,也叫路由. nginx服务器非常核心的配置,一般nginx运维人员在修改nginx配置时,大部分也是围绕着location这个配置进行修改. 下面 ...
- 跨站点请求伪造(CSRF)总结和防御
什么是CRSF 构建一个地址,比如说是删除某个博客网站博客的链接,然后诱使已经登录过该网站的用户点击恶意链接,可能会导致用户通过自己的手将曾经发布在该网站的博客在不知情的情况下删除了.这种构建恶意链接 ...
- angular 实现依赖注入
1:首先获取module对象var myAppModule = angular.module('myApp', []); 2:定义对象(类似spring中xml声明bean对象<bean id= ...
- 2020年腾讯实习生C++面试题&持续更新中(1)
2020年腾讯实习生C++面试题&持续更新中(1) 腾讯面试整理(1) 最近大三的学生找实习生的同学非常多,给大家分享一篇腾讯实习生的面试题,关于面试题,会持续更新~~~ 也算是今天开通博客的 ...
- 前端面试题-WebSocket的实现和应用
(1)什么是WebSocket? WebSocket是HTML5中的协议,支持持久连续,http协议不支持持久性连接.Http1.0和HTTP1.1都不支持持久性的链接,HTTP1.1中的keep-a ...
- 你不知道的事---SringCloud的feign的继承特性
前言 说起SpringChoud的feign大家用过的都说好.Feign是Netflix开发的声明式.模板化的HTTP客户端.对于我们微服务来说,微服务之间的api调用,使用feign来说是再方便不过 ...
- css 箭头三角形
1.向下的三角形 .down{ display:inline-block; width:0px; height:0px; border-top:8px solid rgba(0, 0, 0, 0.65 ...
- npm WARN enoent ENOENT: no such file or directory
https://github.com/visionmedia/debug/issues/261