介绍
在8*8的国际象棋棋盘中放8个皇后,仍以两个皇后都不能互相吃掉,即任意两个皇后不能在同一行同一列或同一对角线。如下图是一种方案。

分析问题
我们可以采用递归+回溯的方式求解,首先将第一个皇后从第一列到第8列试探摆放,比如放在第一列。第2个皇后从第一列到第8列试探摆放,比如放在第3列,依次类推直到放第8个皇后,假设第8个皇后放在第6列满足,再将第8个皇后试探放在第7列第8列。再回溯第7个皇后所在列再试探第8个皇后,再回溯第6个皇后,试探第7个第8个,依次类推。
代码实现
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
package com.eh.ftd.dsa.ds.impl;
/**
* 八皇后(递归+回溯)
*
* @author David Li
* @create 2020/06/18 21:07
*/
public class Queen {
/**
* 皇后个数,确定了皇后个数,棋盘的行数列数也就相应确定了
*/
private int N;
/**
* 存放结果
* 使用a[m]=n表示第m个皇后在第n列
* a[0]不存放值,便于阅读
*/
int[] a;
/**
* 统计方案个数
*/
static int count = 0;
public Queen(int n) {
N = n;
a = new int[N + 1];
}
/**
* 检查已摆放的皇后是否符合要求
*
* @param a
* @param n 第n个皇后
* @return
*/
private boolean check(int[] a, int n) {
for (int i = 1; i < n; i++) {
// 在同一列a[i]=a[n], 在同一斜线, 斜率是1或者-1 也即Math.abs(i-n)==Math.abs(a[i]-a[n])
if (a[i] == a[n] || Math.abs(i - n) == Math.abs(a[i] - a[n])) {
return false;
}
}
return true;
}
/**
* // 从第i个皇后开始试探
*
* @param i
*/
private void solve(int i) {
// 从第一列开始
for (int j = 1; j <= N; j++) {
// 第i个皇后在第j列
a[i] = j;
if (check(a, i)) {
if (i < N) {
solve(i + 1);
} else {
// 已经是摆放的最后一个皇后
count++;
for (int k = 1; k <= N; k++) {
System.out.printf("%d\t", a[k]);
}
System.out.println();
}
}
}
}
public static void main(String[] args) {
Queen queen = new Queen(8);
queen.solve(1);
System.out.printf("方案个数:%d", count);
}
}
|
运行结果
