- /**
- * 回溯法求解 N 皇后問題
- * @author haolloyin
- */
- public class N_Queens {
- // 皇后的個數
- private int queensNum = 4;
- // column[i] = j 表示第 i 列的第 j 行放置一個皇后
- private int[] queens = new int[queensNum + 1];
- // rowExists[i] = true 表示第 i 行有皇后
- private boolean[] rowExists = new boolean[queensNum + 1];
- // a[i] = true 表示右高左低的第 i 條斜線有皇后
- private boolean[] a = new boolean[queensNum * 2];
- // b[i] = true 表示左高右低的第 i 條斜線有皇后
- private boolean[] b = new boolean[queensNum * 2];
- // 初始化變量
- private void init() {
- for (int i = 0; i < queensNum + 1; i++) {
- rowExists[i] = false;
- }
- for(int i = 0; i < queensNum * 2; i++) {
- a[i] = b[i] = false;
- }
- }
- // 判斷該位置是否已經存在一個皇后,存在則返回 true
- private boolean isExists(int row, int col) {
- return (rowExists[row] || a[row + col - 1] || b[queensNum + col - row]);
- }
- // 主方法:測試放置皇后
- public void testing(int column) {
- // 遍歷每一行
- for (int row = 1; row < queensNum + 1; row++) {
- // 如果第 row 行第 column 列可以放置皇后
- if (!isExists(row, column)) {
- // 設置第 row 行第 column 列有皇后
- queens[column] = row;
- // 設置以第 row 行第 column 列爲交叉點的斜線不可放置皇后
- rowExists[row] = a[row + column - 1] = b[queensNum + column - row] = true;
- // 全部嘗試過,打印
- if(column == queensNum) {
- for(int col = 1; col <= queensNum; col++) {
- System.out.print("("+col + "," + queens[col] + ") ");
- }
- System.out.println();
- }else {
- // 放置下一列的皇后
- testing(column + 1);
- }
- // 撤銷上一步所放置的皇后,即回溯
- rowExists[row] = a[row + column - 1] = b[queensNum + column - row] = false;
- }
- }
- }
- // 測試
- public static void main(String[] args) {
- N_Queens queen = new N_Queens();
- queen.init();
- // 從第 1 列開始求解
- queen.testing(1);
- }
- }
- (1,1) (2,5) (3,8) (4,6) (5,3) (6,7) (7,2) (8,4)
- (1,1) (2,6) (3,8) (4,3) (5,7) (6,4) (7,2) (8,5)
- (1,1) (2,7) (3,4) (4,6) (5,8) (6,2) (7,5) (8,3)
- ... ...
- ... ...
- (1,8) (2,2) (3,4) (4,1) (5,7) (6,5) (7,3) (8,6)
- (1,8) (2,2) (3,5) (4,3) (5,1) (6,7) (7,4) (8,6)
- (1,8) (2,3) (3,1) (4,6) (5,2) (6,5) (7,7) (8,4)
- (1,8) (2,4) (3,1) (4,3) (5,6) (6,2) (7,7) (8,5)
- (1,2) (2,4) (3,1) (4,3)
- (1,3) (2,1) (3,4) (4,2)
有時間的話將輸出的結果打印爲直觀一點的符號形式或界面形式更好。