八皇后问题-Java

2023-03-31 13:59:59 浏览数 (1)

八皇后问题

八皇后问题(英文:Eight queens),是由国际象棋棋手马克斯·贝瑟尔于1848年提出的问题,是回溯算法的典型案例。

问题表述为:在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。如果经过±90度、±180度旋转,和对角线对称变换的摆法看成一类,共有42类。计算机发明后,有多种计算机语言可以编程解决此问题。

皇后之间需满足:

  • 不在同一行上
  • 不在同一列上
  • 不在同一斜线上

代码

代码语言:javascript复制
/**
 * @BelongsProject: 
 * @BelongsPackage: 
 * @Author: tangshi
 * @CreateTime: 2023-03-28  14:19
 */
public class EightEmperor {
    /**
     * 棋盘大小 8X8
     */
    public static int checkSize = 4;

    /**
     * 棋盘(一维数组:下标0开始)
     * 注释:数组下标表示行 值表示列
     * 示例:check[4]=3 ->皇后在第4行3列
     */
    private static int check[];

    /**
     * 解法个数
     */
    private static int sum = 0;

    static {
        //生成棋盘,默认值-1表示这行没皇后
        check = new int[checkSize];
        for (int i = 0; i < check.length; i  ) {
            check[i] = -1;
        }
    }

    public static void main(String[] args) {
        System.out.println(checkSize "X" checkSize "解法如下:");
        playChess(check,0);
    }

    /**
     * 放置皇后
     *
     * @param check 棋盘
     * @param index 放置的列,默认开始放第一列
     */
    public static void playChess(int[] check, int index) {
        for (int i = 0; i < checkSize; i  ) {
            //皇后放置在第index行 i列
            check[index] = i;
            //是否可以放置当前位置标识
            boolean is = true;
            //从第index列开始放,所以只需要判断小于index-1列的皇后是否符合规则
            //因为大于index列没有放置皇后,不需要判断
            for (int j = 0; j <= index - 1; j  ) {
                //判断是否对角线 行、列有值
                if (check[j] == i   (index - j) || check[j] == i - (index - j) || check[j] == i) {
                    //不能放置
                    is = false;
                    break;
                }
            }
            if (is) {
                //可以放置,如果是最后一行停止放置,否则继续放置下一行
                if (index==checkSize-1){
                    printf(check);
                }else {
                    playChess(check,index 1);
                }
            } else {
                //不可以放置,重置当前行的值
                check[index] = -1;
            }
        }
    }

    /**
     * 棋盘输出
     * @param check
     */
    public static void printf(int[] check){
        sum  ;
        System.out.println("第" sum "种解法,如图:");
        int[][] ints=new int[checkSize][checkSize];
        for (int i = 0; i < check.length; i  ) {
            ints[i][check[i]]=1;
        }
        for (int i = 0; i < checkSize; i  ) {
            for (int j = 0; j < checkSize; j  ) {
                System.out.print(ints[i][j] "  ");
            }
            System.out.println();
        }
    }
}

输出

代码语言:javascript复制
4X4解法如下:
第1种解法,如图:
0  1  0  0  
0  0  0  1  
1  0  0  0  
0  0  1  0  
第2种解法,如图:
0  0  1  0  
1  0  0  0  
0  0  0  1  
0  1  0  0 

0 人点赞