n皇后問題:
每一行只能有一個皇后,每一列也只能有一個皇后,這個可以用col[edg] 數組來表示某一列是否已經有皇后;
對角線 / 有如下性質: 對於這種方向上經過同一條線的方格,其橫(i) 縱(j)座標的和都相等 i+j, 一共有2*n-1條這種對角線;
對角線\有如下性質:對於這種方向上經過同一條對角線的方格, 其橫(i) 縱(j)座標有如下關係:i - j + n - 1都相等, 一共有2*n條這種對角線。
運行:
8皇后一共有92種解決方案:
=====================0===================
Q * * * * * * *
* * * * Q * * *
* * * * * * * Q
* * * * * Q * *
* * Q * * * * *
* * * * * * Q *
* Q * * * * * *
* * * Q * * * *
=====================1===================
Q * * * * * * *
* * * * * Q * *
* * * * * * * Q
* * Q * * * * *
* * * * * * Q *
* * * Q * * * *
* Q * * * * * *
* * * * Q * * *
=====================2===================
...
代碼:
package cn.agan.recursive;
import java.util.ArrayList;
/**
* 回溯法解決八皇后問題:
*
*/
public class EightQueens {
public static void main(String[] args) {
ChessBoard chessBoard = new ChessBoard(8);
chessBoard.findSolution(0);
chessBoard.printChess();
}
}
class ChessBoard {
private int edg; //棋盤的邊,一般棋盤都是正方形的
private ArrayList<ChessPoint[]> s;
private int[] rows;
private boolean[] col;
private boolean[] dial1;
private boolean[] dial2;
public ChessBoard(int edg) {
this.edg = edg;
s = new ArrayList<>();
rows = new int[edg]; //一個解決方案中,下標表示每一個皇后的第幾行,值表示其列
col = new boolean[edg]; // |
dial1 = new boolean[2*edg - 1]; // /:對於這種方向上經過同一條線的方格,其橫(i) 縱(j)座標的和都相等 i+j
dial2 = new boolean[2*edg - 1]; // \:對於這種方向上經過同一條對角線的方格, 其橫(i) 縱(j)座標有如下關係:i - j + n - 1
}
public void findSolution( int rowIndex) {
if (rowIndex == edg) {
//得到一種解決方案,保存下
saveSolution(rows);
return ;
}
for (int i = 0; i < edg; i++) {
if (!col[i] && !dial1[i+rowIndex] && !dial2[i-rowIndex+edg-1]) {
rows[rowIndex] = i;
col[i] = true;
dial1[i+rowIndex] = true;
dial2[i-rowIndex+edg-1] = true;
findSolution(rowIndex+1);
col[i] = false;
dial1[i+rowIndex] = false;
dial2[i-rowIndex+edg-1] = false;
}
}
return;
}
//保存一個成功的擺放
public void saveSolution(int[] rows) {
ChessPoint[] tmp = new ChessPoint[rows.length];
for (int i = 0; i < rows.length; i++) {
ChessPoint chessPoint = new ChessPoint(i, rows[i]);
tmp[i] = chessPoint;
}
s.add(tmp);
}
//打印所有的解決方案
public void printChess() {
System.out.println("一共有"+s.size() +"種解決方案:");
for (int k = 0; k < s.size(); k++) {
System.out.println("====================="+k+"===================");
ChessPoint[] ps = s.get(k);
for (int i = 0; i < edg; i++) {
for (int j = 0; j < edg; j++) {
if (ps[i].i == i && ps[i].j == j) {
System.out.printf("Q\t");
} else {
System.out.printf("*\t");
}
}
System.out.println();
}
}
}
}
class ChessPoint {
int i;
int j;
public ChessPoint(int x, int y) {
i = x;
j = y;
}
}