八皇后问题的简单解决方法(Java实现)

八皇后问题

八皇后问题内容:

     在8X8的棋盘上放八个皇后要求:
     八个皇后不能在同一条直线上(直线斜线都算)

用递归解决的思路

   判断皇后放的位置满不满足条件
   如果满足条件就放下一个皇后
   要得到全部的满足条件的解我们可以这样做:
   从第一个皇后放到第八个皇后
   因为一共只有八个皇后 
   放到第八个皇后就意味着一个解得出了
   就可以输出一种解
   然后再返回第七个皇后 去尝试第八个皇后的其他放法
   然后返回到第六个皇后 去尝试其他的第七个皇后的放
   法
   以此类推直到返回到第一个皇后
   总体来看 我们是先从第一个皇后到第八个皇后
           然后在从第八个皇后在返回到第一个皇后

代码

因为每一行或者每一列只可能有一个皇后
所以在表示棋盘的时候我们可以只用一个一维数组
用下表和数组里面的数来表示行和列
比如说

int[] array = new int[8]
用i表示行  用array[i]表示列
假如说 array[1]=4
那么这就表示第一(i)行
第四(array[4])列有一个皇后

为了方便理解 让行和列都从0开始,即从0到7
我声明的几个变量如下

    private static int max=8;  //皇后一共的个数
    private static int[] array = new int[max]; //存放皇后排放方式
    public static int number=0//统计解的个数

显示结果的代码

public static void look(){
        for (int i : array) {
            System.out.print(i+" ");
        }
        System.out.println(" ");
    }

这也比较简单 只是把数组里面的数给输出出来了

判断皇后位置是否满足条件的代码

		public static boolean judge(int num) { 
		//判断第num个皇后满不满足要求 满足要求就返回true
        for (int i = 0; i < num; i++) {
            if (array[num]== array[i] || Math.abs(array[num] - array[i]) ==Math.abs(i - num))
            {
                return false;
            }
        }
        return true;
    }

这个代码块的整体思路比较简单

  • 输入进来第几个皇后 然后让这个皇后跟之前的皇后的位置进行比较 如果都不在一条直线上就输出true 否则输出false

关于for里面if的判断可能有些复杂我在这里解释一下

  • array[num]== array[i] 这个很简单 因为array[i]表示的是列所以这判断的就是是否在同一列
  • 因为我们用的是一维数组所以行就不用判断了 毕竟不可能有两个数的下标一样
  • Math.abs(array[num] - array[i]) == Math.abs(i - num)这理解是有点难度的 Math.abs()这个是用来把括号里面的数给变成绝对值的
  • 在棋盘里面如果两个棋子在同一条斜线上那么它们俩行相减的值和列相减的值肯定是一样的

递归代码

这是整个八皇后问题中最复杂 的一部分
我先把代码放到这里

public static void check(int i){
        //i是要开始摆放的第几个皇后  如果摆放到最后一个皇后的时候返回 true并且打印出来
        if(i==max){
            look();
            number++;
            return ;
        }
        for(int j=0;j<max;j++){ //把八个皇后都给放好
            array[i]=j;//先把第i个皇后给放到第i行j列  然后判断行不行
            if(judge(i)){
                check(i+1);
            }
        }
    }

我们从上到下来一点点说这个代码块

 if(i==max){//max就是8 i是输入的第几个皇后
            look();
            number++;//这个是用来统计一共输出了多少次的
            return ;
        }

这一部分是用来返回最后的结果的
因为当第八个皇后确定位置的时候就意味着八皇后问题的一个解就完成了 用look()直接输出然后返回上一级就行了


下面这部分是最难的部分

for(int j=0;j<max;j++){ //把八个皇后都给放好
            array[i]=j;//先把第i个皇后给放到第i行j列
            if(judge(i)){//  然后判断行不行
                check(i+1);
            }
        }

这里面i就是第几号皇后(第几号皇后就放到第几行)
j 就是 i 行 j 列
for循环里面的if实际上起的是筛选的作用
先说0号皇后到7号皇后
假如说1号皇后放到1号位 但是 judge(1)返回值是false
那就继续循环 把1号皇后放到2号位 直到能if能是true为止
以此类推直到

if(judge(i)){
                check(i+1);//这里确定第八个皇后
            }

当第八个皇后确定之后就开始从第八个皇后往第一个皇后反推了
因为有一个for循环 所以能遍历出所有情况
得到的第一个解实际上就是确定了一个基础
然后其他的解都在这个基础上进行变化
比如说第八个皇后移动一位 ,第七个皇后移动一位

全部代码如下

package 八皇后;

public class Queue8 {
    private static int max=8;
    private static int[] array = new int[max];
    public static int number=0;
    public static void main(String[] args) {
    Queue8 qe=new Queue8();
        qe.check(0);
        System.out.println(number);
    }
    public static void check(int i){
        //i是要开始摆放的第几个皇后  如果摆放到最后一个皇后的时候返回 true并且打印出来
        if(i==max){
            look();
            number++;
            return ;
        }
        for(int j=0;j<max;j++){ //把八个皇后都给放好
            array[i]=j;//先把第i个皇后给放到第i行j列  然后判断行不行

            if(judge(i)){

                check(i+1);

            }

        }

    }



    public static boolean judge(int num) { //判断第num个皇后满不满足要求 满足要求就返回true

        for (int i = 0; i < num; i++) {
            if (array[num]== array[i] || Math.abs(array[num] - array[i]) == Math.abs(i - num))
            {
                return false;
            }
        }
        return true;
    }


    public static void look(){
        int[][] array1 = new int[max][max];
        for (int i : array) {
            System.out.print(i+" ");
        }
        System.out.println(" ");
  
    }
}

本人文笔不好水平不高请多包涵

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值