Java-n皇后问题(一维数组)

首先这是我第一次写博客,可能解说的不会太详细,尽量用代码注释补全吧。

n皇后问题是一个很经典的dfs问题,相信每个学习算法的小伙伴都会碰到这个算法,我也是写过了很多回,有用过二维数组的也用过一维的,这次将自己的学习经验分享给同样因为这个问题深受困扰的小伙伴们。

题目
在一张N∗N的国际象棋棋盘上,放置N个皇后,使得所有皇后都无法互相直接攻击得到,(皇后可以直接攻击到她所在的横行,竖列,斜方向上的棋子),现在输入一个整数N,表示在N∗N的棋盘上放N个皇后,请输出共有多少种使得所有皇后都无法互相直接攻击得到的方案数。

输入
一个整数N,代表皇后的个数

输出
输出方案数
样例输入1
4
 

样例输出1
2

样例输入2
8

样例输出2
92


首先我们需要输入一个数N,我们通过一个一维数组queue来表示棋盘,我们用这个queue数组的

下标来表示棋盘是第几行,用数组中的元素来表示是棋盘的第几列。

对于queue数组,当queue[1] = 3 时,证明我在棋盘的第一行第三列放置了一个皇后,因为是一维

数组,我们在递归放置皇后的时候并不需要去储存上一个状态之类的操作,我们只需要通过回溯

更改数组内的元素实现在同一行的不同位置进行放置皇后的操作,并判断此操作是否合法。

相对于二维数组的做法而言,我们只需要判断数组下标和数组元素是否符合皇后的防治法则。

综上所述,我们需要创建一个dfs方法用于实现放置皇后操作,再创建一个chcek方法用来判断当前放置的皇后是否会被攻击

因为是第一次写,也不怎么会说,接下来上代码


import java.util.*;
//n皇后问题

public class Main {
    Scanner in = new Scanner(System.in);
    //接收数据 N
    int N = in.nextInt();
    //这是我们的棋盘,为了更容易看懂,我们忽略掉下标0的位置,以后操作都从第1行开始
    int[] queue = new int[N+1];
    //方案数
    int n = 0 ;
    /*
    首先我们写一个dfs的函数,x代表当前要放置皇后的行数,通过递归往x+1行去执行放置皇后的操作
     */
    void dfs(int x) {
        if(x>N){//这是边界,说明我们已经放完了N行的皇后找到了答案
            n++;
            return;
        }
        for(int i = 1 ; i<=N ; i++){
            queue[x] = i ;  //在第x行的第i列放置一个皇后
            if(check(x)){//判断第x行的皇后是否与前面的起冲突
                dfs(x+1);//说明合法,递归往x+1行放置皇后
            }
        }
    }
    boolean check(int x){
        //从第一行到第x-1行 逐行判断是否合法
        for(int i = 1 ; i<x ; i++){
            //这里为了更清楚的展示,将判断分开
            if(queue[x]==queue[i]){//说明在同一列上,会被攻击
                return false;
            }
            //当第行与行的差值等于列与列的差值时,说明在同一斜线(可以自己画图证明一下)
            if(Math.abs(queue[x]-queue[i])==Math.abs(x-i)){
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        Main m = new Main();
        m.dfs(1);//调用方法,从第1行放置皇后
        System.out.println(m.n);//输出方案数
    }
}

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
皇后问题是指在一个8x8的棋盘上放置8个皇后,使得每个皇后都不会同时攻击到其他皇后。其中,攻击包括在同一行、同一列或同一对角线上。这是一个经典的回溯算法问题,可以使用二维数组来实现。 首先,我们创建一个8x8的二维数组来表示棋盘,用数字1表示皇后的位置,数字0表示空格。然后,从第一行开始,逐行放置皇后,直到所有皇后都放置完毕或无法放置。如果当前行不能放置皇后,则回溯到上一行,重新尝试放置皇后。 以下是Java代码实现: ```java public class EightQueens { private static final int SIZE = 8; private int[][] board = new int[SIZE][SIZE]; // 检查当前位置是否可以放置皇后 private boolean isSafe(int row, int col) { int i, j; // 检查列 for (i = 0; i < row; i++) { if (board[i][col] == 1) { return false; } } // 检查左上角对角线 for (i = row, j = col; i >= 0 && j >= 0; i--, j--) { if (board[i][j] == 1) { return false; } } // 检查右上角对角线 for (i = row, j = col; i >= 0 && j < SIZE; i--, j++) { if (board[i][j] == 1) { return false; } } return true; } // 递归放置皇后 private boolean solve(int row) { if (row == SIZE) { return true; // 所有皇后都已放置 } for (int col = 0; col < SIZE; col++) { if (isSafe(row, col)) { board[row][col] = 1; // 放置皇后 // 递归放置下一行的皇后 if (solve(row + 1)) { return true; } board[row][col] = 0; // 回溯 } } return false; // 无法放置皇后 } // 打印棋盘 private void printBoard() { for (int i = 0; i < SIZE; i++) { for (int j = 0; j < SIZE; j++) { System.out.print(board[i][j] + " "); } System.out.println(); } } public static void main(String[] args) { EightQueens eq = new EightQueens(); if (eq.solve(0)) { eq.printBoard(); } else { System.out.println("无解"); } } } ``` 在以上代码中,`isSafe()`函数用来检查当前位置是否可以放置皇后,`solve()`函数用来递归放置皇后,`printBoard()`函数用来打印棋盘。在`main()`函数中,我们创建`EightQueens`对象并调用`solve()`函数来解决八皇后问题,如果有解,则调用`printBoard()`函数打印结果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值