n後問題:在n*n的×××上放置n個皇后,按照國際象棋的規則,使其彼此不***。即每兩個皇后之間不處於同一行、同一列、同一對角線。
java
首先,行不一樣能夠理解爲第i個皇后必須在第i行,體如今算法中就是當第i個皇后肯定位置後,第i+1個皇后必須在第i+1行尋找知足條件的位置。其次,爲知足列不一樣,須要在第i個皇后選擇位置時,判斷位置的行j,是否在以前全部i-1個皇后中沒有相同的行。最後,關於對角線的判斷能夠使用對角線的知足條件i-j=a-b或i+j=a+b來判斷,即要求當前要判斷的位置的行列和差都與以前已肯定位置的皇后的行列和差不一樣。同時知足上述三個條件才表示第i個皇后的位置是知足要求的,若是第i個皇后在第i行沒法得到知足條件的位置,則表示當前i-1個皇后的位置已不會是有效解,在回溯法的解空間樹中,能夠剪去該結點,無需遍歷該結點的子結點樹,應當進行回溯。算法
package test; import java.util.HashMap; import java.util.Map; /** * Created by saishangmingzhu on 2018/12/15. */ public class EightQueens { public static void main(String[] arg){ new EightQueens().backtracking(); } int n=8; int m=8; int count=0; /** * 回溯法 */ private void backtracking(){ int queeni=0; int i=0; int j=0; for (;j<m;j++) { int[][] chessboard=new int[m][m]; //由於每行只有一個皇后,全部能夠使用Map中的key存儲行,value存儲列 Map<Integer,Integer> queenMap=new HashMap<>(); chessMoves(queeni, i, j, chessboard,queenMap); System.out.println(); } } private void chessMoves(int queeni,int i,int j,int[][] chessboard,Map<Integer,Integer> queenMap){ if (!(judgeRow(i, j,queenMap) == 0 && judgeDiagonal(i, j, queenMap) == 0 )) return ; chessboard[i][j] = 1;//queeni皇后的位置 queenMap.put(i,j); if (queeni + 1<n) { for (int k = 0; k < m; k++) { chessMoves(queeni + 1, i + 1, k, chessboard,queenMap); } } else { print(chessboard); } chessboard[i][j] = 0; queenMap.remove(i); } private void print(int[][] chessboard){ System.out.println("==="+(++count)+"===="); for (int i=0;i<m;i++){ for (int j=0;j<m;j++){ System.out.print(chessboard[i][j]); } System.out.println(); } } /** * 判斷列 * @param i * @param j * @param queenMap * @return */ private int judgeRow(int i,int j,Map<Integer,Integer> queenMap){ for (Integer value:queenMap.values()){ if (value==j){ return 1; } } return 0; } /** * 判斷對角線 * @param i * @param j * @param queenMap * @return */ private int judgeDiagonal(int i,int j,Map<Integer,Integer> queenMap){ for (Integer key:queenMap.keySet()){ int value=queenMap.get(key); if (key-value==i-j || key+value==i+j){ return 1; } } return 0; } }