马上就要蓝桥杯比赛了,我这些算法还是不会,确实有点慌,今天一天早上睡到很晚不愿起床,然后才开始研究8皇后问题。这也是典型的回溯与递归问题。其实本质上和马踏棋盘问题非常类似,八皇后问题呢,就是要判断主对角线,副对角线,横排和竖排不能有皇后。这个是这个问题的着重点。先来看下八皇后问题吧。

1.问题描述:

    在8*8的棋盘中放8个皇后,使得每个皇后不能放在同一行,同一列,同一主对角线上(左下斜),同一副对角线上(右上斜)。

2.输入: 无(当然也可以优化求任意皇后,这个就不是重点了)

3.输出示例:

      1  *  *  *  *  *  *  *
      *  *  *  *  2  *  *  *
      *  *  *  *  *  *  *  3
      *  *  *  *  *  4  *  *
      *  *  5  *  *  *  *  *
      *  *  *  *  *  *  6  *
      *  7  *  *  *  *  *  *
      *  *  *  8  *  *  *  *

    ===============

    1  *  *  *  *  *  *  *
      *  *  *  *  *  2  *  *
      *  *  *  *  *  *  *  3
      *  *  4  *  *  *  *  *
      *  *  *  *  *  *  5  *
      *  *  *  6  *  *  *  *
      *  7  *  *  *  *  *  *
      *  *  *  *  8  *  *  *

    ===============

    ...........

    共有92种方法

4.算法思路:

    这题整体思想是用到递归与回溯,与马踏棋盘非常类似,但是比马踏棋盘问题要难,因为得判断对角线是否冲突,我这里判断是用一个vis[3][20]数组,为什么开始是3呢,因为本身是要判断4个方向不能有皇后的,但是递归是每一列,每一列的递归x,x+1.....这样必然不会在同一列上造成有皇后,则只需要另外3个方向,0表示同一行有皇后,1表示主对角线有皇后,2表示副对角线上有皇后。另外呢,怎么判断这些对角线上是否有皇后 呢?  如果我在第x列,第i行放了元素,那么vis[0][i] = 1表示我在第i行放了元素了。vis[1][x+i] = 1,表示如果我在第x列,第i行放了皇后,那么副对角线上,第x+1列,i-1行数就不能放皇后,第x-1列,第i+1行就不能放皇后,正好都是在副对角线上。vis[2][x-i+8] = 1,表示如果x==i了,那么恒等于vis[2][8] = 1就不能放了,即是主对角线。有了这三个条件既可以了。

5.代码如下:
import java.util.Scanner;

public class EightQueen {
    static int qipan[][] = new int[8][8];
    static int count = 0;
    static int step = 1;
    static int vis[][] = new int[3][20]; //三种情况主对角线,副对角线,行有没有被占用。
    public static void main(String[] args) {
        //初始化棋盘
        for(int i=0;i<8;i++){
            for(int j=0;j<8;j++){
                qipan[i][j] = 0;
            }
        }
        for(int i=0;i<vis.length;i++){
            for(int j=0;j<vis[i].length;j++){
                vis[i][j] = 0;
            }
        }
        
        move(0);
        //从第0个位置开始放第一个皇后,没得说,只要求出皇后的位置,和摆放的数量即可。
        System.out.println("count = " + count);
    }
    public static void move(int x) {
        int next_x = x+1;
        if(step>8){
            for(int i=0;i<8;i++){
                for(int j=0;j<8;j++){
                    if(qipan[i][j] == 0){
                        System.out.printf("%3c",'*'); //把没有皇后,棋盘是0的位置用*输出,显得好看一点
                    }else{
                        System.out.printf("%3d",qipan[i][j]);
                    }
                    
                }
                System.out.println();
            }
            System.out.println("========================");
            count++;
        }else{
            for(int i=0;i<8;i++){
                if(vis[0][i]==0 && vis[1][x+i]==0 && vis[2][x-i+8]==0){//满足摆放条件
                    qipan[x][i] = step;
                    step++;
                    vis[0][i]=1; vis[1][x+i]=1; vis[2][x-i+8]=1;
                    move(next_x);
                    qipan[x][i] = 0;
                    vis[0][i]=0; vis[1][x+i]=0; vis[2][x-i+8]=0;
                    step--;
                    
                }
            }
        }
    }
}

易理解java代码8皇后问题的更多相关文章

  1. 比赛组队问题 --- 递归解法 --- java代码 --- 八皇后问题

    两队比赛,甲队为A.B.C3人,乙队为X.Y.Z3人.已知A不和X比,C不和X.Z比,请编程序找出3队赛手名单 采用了与八皇后问题相似的解法,代码如下: 如有疑问请链接八皇后问题的解法:http:// ...

  2. 从Java代码到字节码(1)

    理解Java代码是如何被编译为字节码并在Java虚拟机(JVM)上执行是非常重要的,这将帮助理解你的程序是如何执行的.这样的理解不仅仅能够让你在逻辑上更好的掌握语言特性,而且能够有机会理解在做出重要决 ...

  3. [改善Java代码]易变业务使用脚本语言编写

    建议16: 易变业务使用脚本语言编写 Java世界一直在遭受着异种语言的入侵,比如PHP.Ruby.Groovy.JavaScript等,这些“入侵者”都有一个共同特征:全是同一类语言—脚本语言,它们 ...

  4. 深入理解Java中的同步静态方法和synchronized(class)代码块的类锁

    一.回顾学习内容 在前面几篇博客中我我们已经理解了synchronized对象锁.对象锁的重入.synchronized方法块.synchronized非本对象的代码块, 链接:https://www ...

  5. Java 虚拟机 最易理解的 全面解析

    先上一个最容易理解的类实例化的内存模型案例截图: 转载自:https://www.zybuluo.com/Yano/note/321063 周志明著的<深入理解 Java 虚拟机>的干货~ ...

  6. Java面向对象理解_代码块_继承_多态_抽象_接口

    面线对象: /* 成员变量和局部变量的区别? A:在类中的位置不同 成员变量:在类中方法外 局部变量:在方法定义中或者方法声明上 B:在内存中的位置不同 成员变量:在堆内存 局部变量:在栈内存 C:生 ...

  7. Java深度理解——Java字节代码的操纵

    导读:Java作为业界应用最为广泛的语言之一,深得众多软件厂商和开发者的推崇,更是被包括Oracle在内的众多JCP成员积极地推动发展.但是对于 Java语言的深度理解和运用,毕竟是很少会有人涉及的话 ...

  8. java代码书写易犯错误

    java代码书写易犯错误: 常见报错: 控制台报错: 找不到或无法加载主类 HelloWorld 原因: java.lang.NoClassDefFoundError: cn/itcast/day01 ...

  9. 操作系统 | 结合 CPU 理解一行 Java 代码是怎么执行的

    根据冯·诺依曼思想,计算机采用二进制作为数制基础,必须包含:运算器.控制器.存储设备,以及输入输出设备,如下图所示. 我们先来分析 CPU 的工作原理,现代 CPU 芯片中大都集成了,控制单元,运算单 ...

随机推荐

  1. Android开发常用的插件及工具

    1.GitHub,这个不管是做安卓还是其他,只要是开发就必上的网站,也是天朝没有墙掉为数不多的网站 2.Stack OverFlow,这个和上面一样,国外非常著名的问答网站,在上面基本上很多问题都可以 ...

  2. es6 Object.assign

    ES6 Object.assign 一.基本用法 Object.assign方法用来将源对象(source)的所有可枚举属性,复制到目标对象(target).它至少需要两个对象作为参数,第一个参数是目 ...

  3. php 处理并发问题

    对于商品抢购等并发场景下,可能会出现超卖的现象,这时就需要解决并发所带来的这些问题了 在PHP语言中并没有原生的提供并发的解决方案,因此就需要借助其他方式来实现并发控制. 方案一:使用文件锁排它锁 f ...

  4. NSData所有API学习

      www.MyException.Cn  网友分享于:2015-04-24  浏览:0次   NSData全部API学习. 学习NSData,在网上找资料竟然都是拷贝的纯代码,没人去解释.在这种网上 ...

  5. pyDash:一个基于 web 的 Linux 性能监测工具

    pyDash 是一个轻量且基于 web 的 Linux 性能监测工具,它是用 Python 和 Django 加上 Chart.js 来写的.经测试,在下面这些主流 Linux 发行版上可运行:Cen ...

  6. Vue.js源码——事件机制

    写在前面 因为对Vue.js很感兴趣,而且平时工作的技术栈也是Vue.js,这几个月花了些时间研究学习了一下Vue.js源码,并做了总结与输出.文章的原地址:https://github.com/an ...

  7. Java面试题库及答案解析

    1.面向对象编程(OOP)有哪些优点? 代码开发模块化,更易维护和修改. 代码复用. 增强代码的可靠性和灵活性. 增加代码的可理解性. 2.面向对象编程有哪些特性? 封装.继承.多态.抽象 封装 封装 ...

  8. Python 运算符,你了解多少?

    新年新气象,文档更新继续~ 一.什么是运算符? 之前我们有定义过变量,变量是用来存储数据的,存储的数据是为了运算,运算就会使用到运算符 举个简单的例子 4 +5 = 9 . 例子中,4 和 5 被称为 ...

  9. Sping Boot入门到实战之入门篇(二):第一个Spring Boot应用

    该篇为Spring Boot入门到实战系列入门篇的第二篇.介绍创建Spring Boot应用的几种方法. Spring Boot应用可以通过如下三种方法创建: 通过 https://start.spr ...

  10. springboot2.0(一):【重磅】Spring Boot 2.0权威发布

    就在昨天Spring Boot2.0.0.RELEASE正式发布,今天早上在发布Spring Boot2.0的时候还出现一个小插曲,将Spring Boot2.0同步到Maven仓库的时候出现了错误, ...