回溯、八皇后

正方形棋盘, 皇后的垂直、水平、对角线方向上 不能有其他皇后。

在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法

/**
 * @author :PangTiemin
 * @date :Created in 2021/7/11 11:08
 * @description: 皇后的垂直、水平、对角线方向上 不能有其他皇后
 * @modified By:
 */
public class Queen {

    //方法个数
    private static int num =0;
    //皇后个数
    private static final int MAXQUEEN=8;
    //每一列皇后所在的行索引
    private static int[]col=new int[8];

    //填第n列的皇后
    public void getCount(int n){
        //当前n列,第几行不能放皇后,true表示不能放
        boolean[] rows = new boolean[MAXQUEEN];

        //遍历n列之前所有列,找到不允许放的位置
        for (int m=0;m<n;m++){
             //水平方向不能放
            rows[col[m]]=true;
            //正斜方向
            int d = n-m;
            //棋盘是正方形,正斜负斜都是按正方形算
            if (col[m]-d>=0){
                //说明 m列皇后位置的正斜方向 与n列相交处没有超过棋盘边缘
                rows[col[m]-d]=true;
            }
            //负斜方向
            if (col[m]+d<MAXQUEEN){
                rows[col[m]+d]=true;
            }
        }

        for (int i=0;i<MAXQUEEN;i++){
            if (!rows[i]){
                //当前列可以放皇后的位置i,但此列还可能有其他位置;
                // 先按这个i位置计算下一列,直到找到n列皇后放在i位的后续列所有方案,在回到n列把皇后放在剩余位置
                col[n]=i;

                //回溯关键,如果当前列能放皇后且不是最后一列,就继续找;
                //如果当前列没有皇后的位置(for循环执行结束),说明方案错误,会递归结束回到上一列,把上一列的皇后换个位置
                //如果当前列是最后一列,且有位置,说明找到方案,输出方案后,看最后一列是否有其他位置能放,没有就回到上一列继续找其他方案
                if (n<MAXQUEEN-1){
                    getCount(n+1);
                } else {
                    //找到一套解决方案
                    num++;
                    System.out.println("第"+num+"套方案");
                    for (int r=0;r<MAXQUEEN;r++){
                        for (int c=0;c<MAXQUEEN;c++){
                            if (col[c]==r){
                                System.out.print(1+" ");
                            }else {
                                System.out.print(0+" ");
                            }
                        }
                        System.out.println();
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        Queen queen = new Queen();
        queen.getCount(0);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值