八皇后回溯 Java版

  

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
public class Queen {
  protected int num = 8;  // the number of queens
  // chessboard索引表示行,即第几个queen,chessboard[i]=value,表示第i+1个queen,位于value+1列
  int[] chessboard = new int[num];
  private static int count = 0;  // 记录多少种摆法
 
  public void lay(int n) {  // n表示放置第几个queen,从0开始
    /*
    n==8时,8个queen已就绪,lay返回,回溯到第8个queen(即第8行),往第八行的下一列继续放置
    当for(int i = 0; i< num; ++i)结束时,表明第8行所有列已经(此时n==7)尝试完毕,继续回溯至n==6,
    即第7行,往第7行的下一列继续尝试(for循环),继续进入n==7的所有i遍历,直至回溯到n==0(第一行)
     */
    if (n == num) {
      print();
      return;
    }
    for (int i = 0; i < num; ++i) {
      chessboard[n] = i; // 将第n+1行的queen至于第i+1列
      if (feasible(n)) {  // feasible会引用当前queen的列数,即chessboard[n]的值
        lay(n + 1); // 当前queen与前面的queen不冲突
      }
    }
  }
 
  /**
   * diagonal有双向,Math.abs(行差) == Math.abs(列差)即diagonal,行差即chessboard索引差,列差即
   * chessboard对应的值差
   *
   * @param n n+1行的queen
   * @return boolean
   */
  public boolean feasible(int n) {  // n 第n+1行queen
    for (int i = 0; i < n; ++i) {
      if (chessboard[i] == chessboard[n] || (n - i) == Math.abs(chessboard[n] - chessboard[i])) {
        return false;
      }
    }
    return true;
  }
 
  /**
   * 找到一种摆法,打印,counter++
   */
  public void print() {
    count++;
    for(int i=0;i<num;++i){
      System.out.print(chessboard[i]+" ");
    }
    System.out.println();
  }
 
  public static void main(String[] args){
    Queen queen=new Queen();
    queen.lay(0);  // 从第1行放置queen
    System.out.println("count: "+count);
  }
}

  

 

复制代码
class Queen {
    private int counter;
    private static final int[] chessboard = new int[8];

    protected void lay(int row) {
        if (row == 8) {
            print();
            return;
        }
        for (int i = 0; i < 8; i++) {
            chessboard[row] = i;
            if (feasible(row)) {
                lay(row + 1);
            }
        }
    }

    private boolean feasible(int row) {
        for (int i = 0; i < row; ++i) {
            if (chessboard[i] == chessboard[row] || row - i == Math.abs(chessboard[row] - chessboard[i])) {
                return false;
            }
        }
        return true;
    }

    private void print() {
        counter++;
        System.out.println("Solution = " + counter);
        for (int i : chessboard) {
            for (int v = 0; v < 8; ++v) {
                System.out.print(v == i ? '$' : '*');
            }
            System.out.println();
        }
    }
}
复制代码

 

posted @   ascertain  阅读(18)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示