java使用回溯法(递归)解决八皇后问题

八皇后问题

在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
通过回溯法(递归)可以解决此问题,经过测试,共有92种摆法。

java实现

思路:

  1. 定一个一维数组,数组大小与皇后数量一致,数组中的每个元素对应一个皇后,数组中的下标对应皇后的行,值对应皇后的列,例如{6 1 5 2 0 3 7 4}, 6说明第一个皇后的坐标为(0,6)
  2. 自定义皇后的数量queenCount, 对应棋盘大小为 queenCount * queenCount,棋盘大小必须大于2*2
  3. 定义totalCount,用于统计在当前大小的棋盘下,一共存在多少种摆放策略
  4. 步骤
    4.1 从第一个皇后开始摆放,若摆放了queenCount个皇后,说明一种策略摆放完毕,输出每个皇后的下标,摆放策略+1
    4.2 分情况讨论
    (1)判断当前皇后的坐标是否与之前的皇后坐标冲突(在同一行同一列或者同一条斜线上),若不冲突继续递归摆放下一个皇后。
    (2)若冲突,将皇后的列+1,继续判断当前坐标是否可用。

代码如下

/**
 * 回溯法解决八皇后问题
 * 1. 定一个一维数组,数组大小与皇后数量一致,数组中的每个元素对应一个皇后
 *   数组中的下标对应皇后的行,值对应皇后的列,例如{6 1 5 2 0 3 7 4}, 6说明第一个皇后的坐标为(0,6)
 * 2. 自定义皇后的数量queenCount, 对应棋盘大小为 queenCount * queenCount,棋盘大小必须大于2*2
 * 3. 定义totalCount,用于统计在当前大小的棋盘下,一共存在多少种摆放策略
 * 4. 步骤
 *  4.1 从第一个皇后开始摆放,若摆放了queenCount个皇后,说明一种策略摆放完毕,输出每个皇后的下标,摆放策略+1
 *  4.2
 *  (1)判断当前皇后的坐标是否与之前的皇后坐标冲突(在同一行同一列或者同一条斜线上),若不冲突继续递归摆放下一个皇后。
 *  (2)若冲突,将皇后的列+1,继续判断当前坐标是否可用
 */
public class BackTrace {

    private int[] arrayQueen;

    private int queenCount;

    static int totalCount = 0;

    public BackTrace(int size){
        if (size < 3){
            throw new RuntimeException("宫格的大小必须大于等于3!");
        }
        this.queenCount = size;
        this.arrayQueen = new int[size];
    }


    private void addQueen(int n){
        if (n == queenCount){//全部放满,直接输出
            totalCount ++;
            print();
            return;
        }
        for (int i =0; i < queenCount; i ++){
            arrayQueen[n] =i;
            if (!isConflict(n)){
                addQueen(n + 1);
            }
        }
    }

    /**
     * 打印每种放法
     */
    private void print(){
        for (int j =0 ; j < arrayQueen.length; j++){
            System.out.print(arrayQueen[j] + " ");
        }
        System.out.println("");
    }

    /**
     * 判断是否有皇后在同一行同一列或者同一条斜线上
     */
    private boolean isConflict(int n){
        for (int i =0; i < n; i ++){
            if (arrayQueen[i] == arrayQueen[n] || Math.abs(n - i) == Math.abs(arrayQueen[n] - arrayQueen[i])){
                return true;//有皇后和当前皇后处于同一列
            }
        }
        return false;
    }

    public static void main(String[] args) {
        BackTrace trace = new BackTrace(8);
        trace.addQueen(0);
        System.out.println("总共有:" + totalCount + "种摆法");
    }
}

测试结果:


image.png

验证:
以 7 2 0 5 1 4 6 3 为例,通过八皇后小游戏进行验证(最下边一行表示第一行),结果正确。


VmAUmYuk8y.jpg

欢迎留言,我们一起成长~~

你可能感兴趣的:(java使用回溯法(递归)解决八皇后问题)