八皇后问题算法

八皇后问题算法

  • 问题引入:在八行八列的格子上放8个皇后(棋子),使得任意两个皇后都攻击不到对方,即使得他们都不在同一行同一列和同一斜线上

  • 思路分析:

    1. 第一个皇后放在第一行第一列;
    2. 第二个皇后放在第二行第一列,判断是否满足,如果不满足,则继续放在第二列、第三列,依次放完所有列,找到合适的位置;
    3. 继续把第三个皇后放在第三行第一列、第二列....直到第8个皇后也能放在一个不冲突的位置,说明找到一个8皇后解了;
    4. 当找到正确解后,在栈回退到上一个栈时,就会开始回溯,即把第一个皇后放在第一列的所有正解都得到;
    5. 然后回头继续第一个皇后放在第二列,继续执行前面的所有步骤。
  • 说明:

    理论上应该创建一个二维数组表示棋盘,但是实际上可以通过算法,用一个一维数组就可以解决,如:

    Array[8]={0,4,7,5,2,6,1,3};

    数组的下标表示第几行,即第几个皇后,下标0表示第1一个皇后;数组的每一个值表示第i+1个皇后放在第i+1列。

  • 核心方法:

    • 方法1,将皇后的位置输出。
    • 方法2,检查放置当前皇后是否冲突。
    • 方法3,用于放置第n个皇后,使用了递归思想,select每一次递归时,进入到select中都由一个for循环,会由回溯。
  • 代码实现

package com.guodaxia.recursion;

/**
 * @ author Guo daXia
 * @ create 2022/11/20
 */
public class Queue8 {
    public static void main(String[] args) {
        //创建当前类对象
        Queue8 queue8= new Queue8();
        queue8.select(0);//从第一个皇后开始
        System.out.printf("一共有%d解法\n",count);
        System.out.printf("一共判断冲突的次数%d次\n",judgeCount);
    }
    static int count =0;
    static int judgeCount = 0;
    //8个皇后
    int max=8;
    //数组保存正解
    int[] array = new int[max];
    //方法3,用于放置第n个皇后,使用了递归思想,select每一次递归时,进入到select中都由一个for循环,会由回溯
    private void select(int n){
        if (n==max){
            //如果n=8,则8个皇后放好了
            print();//打印
            return;//结束
        }
        //依次放入皇后,需要判断是否冲突
        for (int i = 0; i < max; i++) {//i代表对某行  列扫描
            //第一个皇后固定在第一行第一列
            array[n]=i;
            //判断
            if (judge(n)){//judge方法true,表示不冲突
                //接下来放置n+1个皇后,递归
                select(n+1);
            }
            //接下来是冲突,继续执行array[n]=i;即将第n个皇后放在本行中的后移一个位置
        }
    }
    /**
     * 方法2,检查放置当前皇后是否冲突
     * @param n 表示第n个皇后
     * @return 返回false,则冲突;返回true,则不冲突
     */
    private boolean judge(int n){
        judgeCount++;
        for (int i = 0; i < n; i++) {
            //情况1,判断是否同一列,array[i]==array[n]
            //情况2,判断是否同一斜线上,行差==列差
            //情况3,是否同一行,因为n代表第n个皇后,所以不会同一行
            if (array[i]==array[n]||Math.abs(n-i)==Math.abs(array[n]-array[i])){
                return false;
            }
        }
        return true;
    }
    //方法1,将皇后的位置输出
    private void print(){
        count++;
        for (int i = 0; i < array.length; i++) {
            System.out.printf(array[i]+"");
        }
        System.out.println();
    }
}
posted @ 2022-11-20 23:01  郭培鑫同学  阅读(105)  评论(0编辑  收藏  举报