经典问题,教科书式解题过程,可是在判断布局的合法性上徘徊了很久,逻辑一如既往的混乱,希望这只是由于太累的缘故,其实也只是为了练练手,感觉回溯那部分的代码十分好写,主要还是逻辑上的问题比较费劲。
public class EightQueen {
private int[][] chess;
private int[] used;//列数已用标记,在构造函数中初始化为-1
private int length;
public static void main(String[] args) {
EightQueen eq = new EightQueen(4);
eq.trial(0);
}
public EightQueen(int n) {
this.chess = new int[n][n];
this.used = new int[n];
for (int i = 0; i < n; i++)
used[i] = -1;
this.length = n;
}
public void trial(int i) {
//输出当前布局
if (i == length) {
System.out.println("——————————————");
for (int r = 0; r < length; r++) {
System.out.print("|");
for (int c = 0; c < length; c++) {
if(chess[r][c]==1)
System.out.print(" X ");
else
System.out.print(" O ");
}
System.out.println("|");
}
System.out.println("——————————————");
} else
for (int j = 0; j < length; j++) {
chess[i][j] = 1;//在第i行第j列放置皇后
if (condition(i, j)) {//布局合法则把此列标记为此行的行数
used[j] = i;
trial(i + 1);//向下递归
}
//回溯
if (used[j] == i)
used[j] = -1;//当回溯到i行时,撤销对此行的列标记
chess[i][j] = 0;//移走皇后
}
}
public boolean condition(int i, int j) {
boolean var = true;
if (i > 0) {
if (used[j] != -1) {
var = false;//一列只能有一个皇后
}
else {
if (j != 0 && j != length - 1) {
if (chess[i - 1][j - 1] == 1 || chess[i - 1][j + 1] == 1)
var = false;//非边界的皇后的左上对角或右上对角不能有皇后
}
//边界上的皇后合法性判定
if (j == 0) {
if (chess[i - 1][j + 1] == 1)
var = false;
}
if (j == length - 1) {
if (chess[i - 1][j - 1] == 1)
var = false;
}
}
}
return var;
}
}