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;
}
}