关于N皇后问题解题思路(Java)

一、问题介绍

八皇后问题,是一个古老而著名的问题,是回溯的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即:任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

二、解题思路

1) 第1个皇后先放(1,1)
2) 第2个皇后放在(2,1),然后判断是否OK[即判断是否合法], 如果不OK,继续放在(2,2)、(2,3)、……(2,N)找到一个合法的位置。
3) 按照步骤2)继续寻找第3个皇后、第4个皇后,……第8个皇后。若皇后x未找到合法位置,则回溯到皇后x-1,寻找皇后x-1的另一个合法的位置,再继续寻找皇后x、皇后x+1,……皇后N。
4) 当找到第8个皇后的合法位置时,则表明找到一个正解。
5) 可继续往后寻找,找到所有的方案

三、代码实现

1、说明

array[0]不使用,array[1]为第一个皇后的位置,array[2]为第一个皇后的位置……

public class QueenTest {
    int N;//N皇后
    int[] array = new int[N + 1];//N皇后的位置
    int count = 0;//记录方案数量

    //构造器
    public QueenTest(int n) {
        N = n;
    }

    //打印方案
    void print(int[] array) {
        count++;
        System.out.print("方案" + count + ":");
        for (int i = 1; i <= N; i++) {
            System.out.print(array[i] + " ");
        }
        System.out.println();
    }
}

2、判断第i个皇后是否合法

说明:由于我们是按顺序依次,按行寻找皇后的位置的,不用判断皇后是否在同一行。只需判断两个皇后是否同一列同一斜线上。同一斜线:即表明两皇后位置的斜率的绝对值为1

    Boolean judge(int i) {
        for (int j = 1; j < i; j++) {
            if (array[j] == array[i] || Math.abs(i - j) == Math.abs(array[i] - array[j])) {
                return false;
            }
        }
        return true;
    }

3、求解N皇后的方案1--非递归/回溯

说明:按照上面解题思路,写的代码

    void queen() {
        int i = 1;//放置第i个皇后
        while (i >= 1 && i <= N) {
            array[i]++;//寻找第i个皇后的位置
            while (array[i] <= N && !judge(i)) {//判断第i个皇后的位置是否合法
                array[i]++;
            }
            if (array[i] <= N) {//第i个皇后找到一个合法位置
                if (i == N) {
                    print(array);//打印方案
                } else {
                    i++;寻找下一个皇后的位置
                }
            } else {//第i个皇后找到一个合法位置
                //回溯
                array[i] = 0;
                i--;
            }
        }
    }

3、求解N皇后的方案2--递归

说明:传入的参数x为1!!!

    void queen(int x) {//求解第x个皇后的位置,传入x=1
        for (int i = 1; i <= N; i++) {
            array[x] = i;//寻找第x个皇后的位置
            if (judge(x)) {//判断合法性
                if (x == N) {//递归退出的条件
                    print(array);
                } else {
                    queen(x + 1);//求解第x+1个皇后的位置
                }
            }
        }
    }

4、测试代码main函数

说明:调用上面写的类方法

    public static void main(String[] args) {
        QueenTest queenTest = new QueenTest(8);
//        queenTest.queen();
//        System.out.println("一共有" + queenTest.count + "种方案");

        queenTest.queen(1);
        System.out.println("一共有" + queenTest.count + "种方案");

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值