8皇后问题解决
8皇后问题这里不复累赘,之前一直有听过大神说这是递归的经典案例,但一直不清楚如何用递归实现。今天偶尔百度了一下8皇后的百度百科,扫了一眼代码,知道了思路,然后自己用代码实现了,算法非原创,勿喷。写这blog只是为了自己更好的理解8皇后问题的分析思路。
分析看棋盘
45°对角线用黑色表示,135°对角线用蓝色。
每种对角线条数2n-1。我们编号从0开始
当棋子落在棋盘的位置为(r,c)的时候,占据的45°对角线编号为r+c,
135°对角线编号为row + r - c - 1,其中row为棋盘的行列数。因此可以将此作为我们判断棋子是否可落的重要依据。即当坐标(r,c)上有皇后时,棋盘上第c列,黑色对角线r+c,蓝色对角线row + r - c - 1占据的格子不能有皇后。用代码实现:
if (column[c] == 0 && dline45[c + r] == 0 && dline135[row + r - c- 1] == 0) {
//code body
//落子的逻辑
}
请看完整代码
public class MyQueen {
//棋盘行列数
private int row;
//解法个数
private int num=0;
// 皇后的位置
private int[][] queen;
// 第几列有皇后,1标识有皇后
private int[] column;
// 45°对角线上1,1标识有皇后
private int[] dline45;
// 135°对角线上1,1标识有皇后
private int[] dline135;
public MyQueen(int row) {
this.row = row;
queen = new int[row][row];
column = new int[row];
dline45 = new int[row * 2 - 1];
dline135 = new int[row * 2 - 1];
for (int i = 0; i < column.length; i++) {
column[i] = 0;
}
for (int i = 0; i < dline45.length; i++) {
dline45[i] = 0;
dline135[i] = 0;
}
}
/**
*
* @param column
* 棋子放置的列编号
*/
public void placeChess(int r) {
if (r >= row) {
// 打印放置点
System.out.println("方案"+(++num));
printResult(queen);
return;
}
for (int i = 0; i < row; i++) {
if (column[i] == 0 && dline45[i + r] == 0 && dline135[row + r - i - 1] == 0) {
column[i] = dline45[i + r] = dline135[row + r - i - 1] = 1;
queen[r][i] = 1;
//递归下一行
placeChess(r + 1);
// 位置不对,重新放置
column[i] = dline45[i + r] = dline135[row + r - i - 1] = 0;
queen[r][i] = 0;
}
}
}
private void printResult(int[][] queen) {
for (int i = 0; i < queen.length; i++) {
for (int j = 0; j < queen[i].length; j++) {
System.out.print(queen[i][j]);
}
System.out.println();
}
}
public int[][] getResut() {
placeChess(0);
return queen;
}
终于解决了一个心里存在已久的问题,如释重负!