八皇后问题(Queen8)思路分析+源码

问题描述

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

思路分析
  1. 第一个皇后先放在第一行的第一列
  2. 第二个皇后放在第二行的第一列,判断是否合适,若不合适放在第二列、第三列···直到找到一个合适位置
  3. 继续放置第三个皇后,和步骤2相同。直到第八个皇后放置在一个不冲突的位置。此时找到了一个正解
  4. 当得到一个正解时,在栈回退到上一个栈时,就开始回溯,即将第一个皇后放置在第一列的所有正解全部得到
  5. 然后回头,继续将第一个皇后放在第二列,后面循环执行1,2,3,4的步骤
代码理解

array[i] == array[n]条件成立,表明两个皇后在同一列
Math.abs(n - i) == Math.abs(array[n] - array[i]) 相当于
Math.abs(n - i) / Math.abs(array[n] - array[i])==1(即斜率为1)

代码及注释详解
package package07;

public class Q8 {
    //定义一个max,表示共有多少个皇后
    int max=8;
    //定义一个数组array,保存皇后放置位置的结果
    int[] array=new int[max];
    //记录正解的个数
    static int count = 0;
    //记录判断冲突的次数,可以不用写
    static int judgeCount = 0;
    //主方法
    public static void main(String[] args) {
        //new 一个Q8的对象
        Q8 q8 = new Q8();
        //调用 check() 方法
        q8.check(0);
        System.out.println("一共有"+count+"种解法");
        System.out.println("一共判断冲突次数"+judgeCount);
    }
    private void check(int n){
        //如果皇后放置完了,结束该方法
        if(n==max){
            //调用 print() 方法
            print();
            return;
        }
        //依次放入皇后,并判断是否冲突
        for (int i = 0; i < max; i++) {
            //先把当前这个皇后 n ,放在第一列,并将皇后的位置记录在数组array中
            array[n] = i;

            //判断当前放置第 n 个皇后到 i 列时,是否冲突
            if (judge(n)) {
                //如果不冲突,继续放第 n+1 个皇后,即开始递归
                check(n + 1);
            }
            //如果冲突了,就继续执行 array[n]=i;即将第 n 个,放置在本行,后移一位
        }
    }

    //判断是否冲突
    private boolean judge(int n) {
        judgeCount++;//执行一次,判断冲突次数 +1
        for (int i = 0; i < n; i++) {
            if (array[i] == array[n] || Math.abs(n - i) == Math.abs(array[n] - array[i])) {
                return false;
            }
        }
        return true;
    }

    //找到一个正解时,打印出一个正解数组,数组元素就是正解的位置
    private void print() {
        count++;//正解数+1
        //for循环输出一个正解
        for (int i = 0; i <array.length ; i++) {
            System.out.print(array[i] + "");
        }
        System.out.println();
    }
}
代码运行结果

04752613
05726314
06357142
06471352
13572064
14602753
14630752
15063724
15720364
16257403
16470352
17502463
20647135
24170635
24175360
24603175
24730615
25147063
25160374
25164073
25307461
25317460
25703641
25704613
25713064
26174035
26175304
27360514
30471625
30475261
31475026
31625704
31625740
31640752
31746025
31750246
35041726
35716024
35720641
36074152
36271405
36415027
36420571
37025164
37046152
37420615
40357162
40731625
40752613
41357206
41362750
41506372
41703625
42057136
42061753
42736051
46027531
46031752
46137025
46152037
46152073
46302751
47302516
47306152
50417263
51602473
51603742
52064713
52073164
52074136
52460317
52470316
52613704
52617403
52630714
53047162
53174602
53602417
53607142
57130642
60275314
61307425
61520374
62057413
62714053
63147025
63175024
64205713
71306425
71420635
72051463
73025164
一共有92种解法
一共判断冲突次数15720

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值