递归解决八皇后问题


递归解决八皇后问题

√八皇后问题说明

  • 八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。

  • 该问题是国际西洋祺棋手马克斯贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击

  • 即:任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

√八皇后思路分析

1)第一个皇后先放第一行第一列 arr[8] = {0,0}

2)第二个皇后放在第二行第一列、然后判断是否OK, 如果不OK,继续放在第二列、第三列、依次把所有列都放完,找到一个合适

3)继续第三个皇后,还是第一列、第二列.直到第8个皇后也能放 在一个不冲突的位置,算是找到了一个正确解

4)当得到一个正确解时,在栈回退到上一个栈时,就会开始回溯,即 将第一个皇后,放到第一列的所有正确解,全部得到.

5)然后回头继续第一个皇后放第二列,后面继续循环执行1,2,3,4的 步骤

说明:理论上应该创建一个二维数组来表示棋盘,但是实际上可以通 过算法,用一个一维数组即可解决问题

例如 : arr[8]={0,4,7,5,2,6,1,3} ,我们可以使用这样的一维数组来解决问题, 例如该数组 就是将皇后摆放到 ,第一行的第一列 ,第二行的第五列 ………

 

代码示例(通过视频参考,对着敲出来的)

public class Eight_questions {
  public static void main(String[] args) {

      checkerboard c1 = new checkerboard();
      c1.check(8,0);

  }
}

class checkerboard {
  int [] arr= new int[8];
  int count = 0;
  public void check(int n, int index) {
      if (n == index){
          for (int i = 0;i < n ;i++){
              System.out.print(arr[i]+" ");
          }
          count+=1;

          System.out.println();
          System.out.println("第"+count+"种摆放");

      }else {
          for (int i = 0;i < n ;i++){
              //此时的n代表列
              arr[index] = i;
              //第index行第i列
              if (judge(index)){
                  check(n,index + 1);
              }
          }
      }


  }

  public boolean judge(int index){
      for (int i=0;i<index;i++){
          if (arr[i]==arr[index]||Math.abs(index - i)==Math.abs(arr[index]-arr[i])){
              return false;
          }
      }
      return true;
      //如果不起冲突就返回true
  }

}

 

实际分析一下代码

class checkerboard

创建一个类 ,用于实现八皇后的棋盘填充

 int [] arr= new int[8];
//在类中创建一个全局变量数组,因为下面有两个方法需要使用到
public void check(int n, int index) {
//创建方法check,传参的参数 n为皇后棋子的个数,index表示从第几行开始
      if (n == index){
      //如果棋子个数和和行数一致表示皇后已经全部下完
          for (int i = 0;i < n ;i++){
          //循环行数对数组进行遍历,然后将数组的内容打印出来
              System.out.print(arr[i]+" ");
          }
          count+=1;
          System.out.println();
          System.out.println("第"+count+"种摆放");
      }
//如果数组没有完成填充(也就是八皇后的棋子没有下完)
else {
      for (int i = 0;i < n ;i++)
      //循环
      {
          //此时的n代表列
          arr[index] = i;
          //循环填充数组的内容
          //第index行第i列
          if (judge(index)){
          //接收judge方法来判断这个位置是否符合规范,若符合规范就执行下面的递归
          check(n,index + 1);
          //递归调用方法,每次添加都会增加一次行数
        }
      }
  }
public boolean judge(int index){
//这个方法主要用于判断皇后放置是否合法,接收参数index表示每行进行判断
      for (int i=0;i<index;i++){
      //循环
          if (arr[i]==arr[index]||Math.abs(index - i)==Math.abs(arr[index]-arr[i])){
          //判断数组的上下两行放置的列是否一致(如若一致表示皇后在同一列触犯了规则)
          //判断数组的上下两行,通过两个位置横纵坐标互减如果数值一致就说明在一条斜线之上
          //同时由于不可能同行因此不判断同行的情况
              return false;
              //如果不符合判断就返回false
          }
      }
      return true;
      //如果符合规范就返回true
  }

 

原创文章,作者:bd101bd101,如若转载,请注明出处:https://blog.ytso.com/245306.html

(0)
上一篇 2022年4月18日
下一篇 2022年4月18日

相关推荐

发表回复

登录后才能评论