zoukankan      html  css  js  c++  java
  • 八皇后问题

    昨天学习了下八皇后问题的递归写法,觉得很有意思,贴上来小结一下。这个问题可以通过二维数组的穷举来计算结果,但是用一维数组看起来更巧妙,代码也很简洁。

    数组的0下标表示第0行,1下标表示第1行......依次类推。

    按照一般穷举的思路,我们从棋盘的[0,0]坐标开始摆放皇后,这个坐标可以通过arr[0] = 0 这种方式来表达,下标0表示存在第0行,值0表示在第0列,将本来用二维数组表示的期盼简化成一维数组。

    1.第一个皇后存在0列,固定好这个位置,开始循环遍历,寻找第二个皇后的位置,在judge方法中,对后续摆放的皇后的位置进行判断,是否可行,判断的方式是:

     前面的表达式判断是否在同一行,后面的是判断他们是否在同一斜线上,如果在的话,x轴的坐标差长度等于y轴坐标差长度

    2.通过上面的判断,我们在遍历中判断传入的列坐标是否可行,如果可以,递归进入n+1,寻找下一个皇后的位置

    3.重复1,2的过程,直到:

    执行到n=8,说明put(7)已经结束,走到了put(7)的出口,但是put(7)结束不表示程序的结束,put(6)的for循环中,i++,再执行下一轮put(7),直到put(6)的for循环遍历结束,又回溯到put(6)中,不断重复这个过程直到回溯到put(0),将put(0)中循环遍历结束程序才终止。

    代码如下:

     1 package com.vi.test;
     2 
     3 import java.util.Arrays;
     4 
     5 //  八皇后问题
     6 public class TestRecurision {
     7     private static final Integer[] arr = new Integer[8];
     8     private static int count = 0;
     9 
    10     //  n表示第几个皇后,在主方法中传入一个0,说明是从第0个皇后开始
    11     private static void put(int n) {
    12         if (n == 8) {
    13             count++;
    14             print();
    15             //  已经轮到第9个皇后,说明前面的都已经放好了,当前这轮游戏结束,开始下一轮,直到所有的排法都被遍历,程序在这里退出
    16             return;
    17         }
    18         //  循环遍历存放位置,判断是否可行,如不可行,换下个位置
    19         for (int i = 0; i < 8; i++) {
    20             arr[n] = i;
    21             if (judge(n)) {
    22                 put(n + 1);
    23             }
    24         }
    25     }
    26 
    27     //  判断在当前行第n列摆放皇后是否可行
    28     private static boolean judge(int n) {
    29         for (int i = n - 1; i >= 0; i--) {
    30             //  如果这个皇后摆在和前面元素同一列或者同一条斜线上,则说明当前位置不可行
    31             if (arr[n] == arr[i] || Math.abs(i - n) == Math.abs(arr[i] - arr[n])) {
    32                 return false;
    33             }
    34         }
    35         return true;
    36     }
    37 
    38     //  打印皇后组合
    39     private static void print() {
    40         System.out.println(Arrays.asList(arr));
    41     }
    42 
    43     public static void main(String[] args) {
    44         put(0);
    45         System.out.println("共有" + count + "种解法");
    46     }
    47 
    48 }

    最终程序的结果:

  • 相关阅读:
    再谈树形dp
    洛谷 P3627 [APIO2009]抢掠计划
    树状数组
    树形dp 入门
    洛谷P2014 选课
    洛谷P2015 二叉苹果树
    9 vue.js 被观察数组的变异方法
    8 vue的v-model指令学习
    7vue-事件修饰符
    6.vue事件绑定-click
  • 原文地址:https://www.cnblogs.com/blogforvi/p/13817146.html
Copyright © 2011-2022 走看看