/**
* 回溯法求解n皇后问题——递归实现
*
* 过程描述
* 从第n(1, 2, ...)行开始,遍历当前行,找出当前行中所有可放置皇后的位置,并将其当作各个节点
* 若当前行中存在可放置皇后的位置,则根据"深度优先"的原则,从当前行中第一个节点开始继续遍历下一行,
* 当行号大于皇后个数时,遍历结束,输出遍历结果
*
* 若当前行中不存在可放置皇后的位置,则跳转至位于上一行的父节点,从父节点开始继续寻找可放置皇后的位置(回溯);
*
*/
public class N_Queens {
private int n;
private int[] x;
private long sum;
public N_Queens() {
this.sum =
0;
this.n =
8;
this.x =
new int[n +
1];
}
/**
*
* @param k——棋盘行号,棋盘中的第k行——t
* @param j——棋盘列号,棋盘中的第j列
*
*******************************************************************************
*
* x[j]——皇后j放在第j行的x[j]列
*
*******************************************************************************
*
* x[j] == x[k]——两个皇后处在同一列
*
* j = 1, x[j] = 2
* k = 2, x[k] = 2
*
*******************************************************************************
* (Math.abs(k - j) == Math.abs(x[j] - x[k])——两个皇后处在同一行或同一斜线或同一反斜线
*
* 两个皇后处在同一行
* j = 2, x[j] = 2
* k = 3, x[k] = 3
*
* 两个皇后处在同一斜线
* j = 1, x[j] = 1
* k = 2, x[k] = 2
*
* 两个皇后处在同一反斜线
* j = 2, x[j] = 1
* k = 1, x[k] = 2
*
*******************************************************************************
*
* @return
*/
public boolean place(
int k) {
for (
int j =
1; j < k; j++) {
if ((Math.abs(k - j) == Math.abs(x[j] - x[k])) || (x[j] == x[k])) {
return false;
}
}
return true;
}
/**
* 回溯,完成主要的求解操作
*
* @param t——回溯到的行数(棋盘行号:棋盘中的第t行)
* @param n——皇后数目(棋盘行数,棋盘列数)
*/
public void backTrace(
int t) {
if (t > n) {
sum++;
System.out.println(
"方案 " + sum);
print(x);
System.out.println(
"\n----------------\n");
}
else {
for (
int i =
1; i <= n; i++) {
x[t] = i;
if (place(t)) {
backTrace(t +
1);
}
}
}
}
/**
* 打印可行放置方案
*
* @param a
*/
public void print(
int[] a) {
for (
int i =
1; i < a.length; i++) {
System.out.print(
"皇后" + i +
"(" + i +
", " + a[i] +
") ");
}
}
public static void main(String[] args) {
N_Queens em =
new N_Queens();
em.backTrace(
1);
System.out.println(
"详细方案如上所示," +
"可行个数为:" + em.sum);
}
}
转载请注明原文地址: https://ju.6miu.com/read-673754.html