算法N皇后--Java及JavaScript实现

1、问题描述
在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子,如图a所示。n后问题等价于在n×n格的棋盘上放置n个皇后,任何2个皇后不放在同一行或同一列或同一斜线上,如图b所示

在这里插入图片描述
算法分析

  1. 用x[i]表示皇后i放在棋盘的第i行的第x[i]列, x[j]表示皇后j放在棋盘的第j行的第x[j]列。
  2. 由于不允许将2个皇后放在同一行所以:i≠j 由于不允许将2个皇后放在同一列所以:x[i]≠ x[j]
  3. 由于2个皇后不能放在同一斜线上,即不处于同一正、反对角线,所以:
  4. |i-j|≠| x[i]-x[j]| 因此,n皇后彼此不受攻击的条件为:i≠j且x[i]≠ x[j]且|i-j|≠|x[i]-x[j]|
    在这里插入图片描述
    这种问题可以采用回溯法,
    皇后1在第一行放置后,
    皇后2在第二行放置的位置依赖于皇后1放置的位置,
    皇后3在第三行放置的位置依赖于皇后1和2的位置

    在这里插入图片描述
    Java实现代码
import static java.lang.Math.abs;
public class N_queen {
    int[] x;//x存储皇后的位置,下标加1代表行数,下标对应的值代表列数
    int n ;//n代表层数或者皇后位数
    public N_queen(int n){
        this.n=n;
        x=new int[n+1];
    }
    public void backtrack(int t) {
        //t代表所在的层数,从t=1开始
        if (t > n) {    //t>n表示已经达到叶节点
            // 打印结果
            for (int a = 1; a <= n; a++) {
                System.out.print("(第" + a+"行"+ "第"+x[a]+"个)  ");
            }
            System.out.println();
        } else
            for (int i = 1; i <= n; i++) {
                //i代表每个节点下都有4个节点
                //t记录第t行  x[t]记录第t行放置皇后的位置
                x[t] = i;
                //如果x[t]可以放置皇后,则继续进行深度搜索
                if (place(t)){
                    backtrack(t + 1);
                }
            }
    }
    //判断(k行i列)是否可以放置皇后
    private boolean place(int k) {
        for (int j = 1; j < k; j++)
            //(x[j] == x[k]代表列对齐
            //abs(k - j) == abs(x[j] - x[k])代表斜线对齐
            if ((x[j] == x[k]) || (abs(k - j) == abs(x[j] - x[k])))
                return false;
        return true;
    }
    public static void main(String[] args) {
        N_queen n_queen=new N_queen(4);
        n_queen.backtrack(1);
    }
}

运行结果
在这里插入图片描述
棋盘表示
在这里插入图片描述
JavaScript实现

// 立即执行函数
(function () {
    let n = 4;// 皇后的位数
    let x = new Array(n + 1);//x记录皇后的位置
    let str;
    function backTrack(t) {//t为所在n叉树的层数
        // 当前节点是叶节点 则打印
        if (t > n) {
            str = "";
            for (let a = 1; a <= n; a++) {
                str += "(第"+a+"行,"+"第"+ x[a]+"列) ";
            }
            console.log(str);
        } else {
            for (let i = 1; i <= n; i++) {
                x[t] = i;//皇后t放置在棋盘的第t行第i列
                //判断皇后t放置的位置是否正确 正确则继续深度搜索
                if (place(t)) {
                    backTrack(t + 1);
                }
            }
        }
    }
    //判断皇后k放置的位置是否正确
    function place(k) {
        for (let j = 1; j < k; j++) {
            //x[j] == x[k] 列对齐
            //Math.abs(j - k) == Math.abs(x[j] - x[k]) 斜对齐
            if (x[j] == x[k] || Math.abs(j - k) == Math.abs(x[j] - x[k]))
                return false;
        }
        return true;
    }
    backTrack(1);
})();

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值