Java遞迴解決n皇后問題
阿新 • • 發佈:2018-12-11
題目
八皇后問題是一個以國際象棋為背景的問題:如何能夠在 8×8 的國際象棋棋盤上放置八個皇后,使得任何一個皇后都無法直接吃掉其他的皇后?這道題目也可以稍微延伸一下,變為 N×N的棋盤上放置N個皇后,其他條件相同。 下面介紹一種比較簡單易懂的實現方式。
程式碼
import java.util.ArrayList; import java.util.List; /** * Created by GuanDS on 2018/9/20. */ public class Queen { public static void main(String[] args) { long currentTime = System.currentTimeMillis(); int n = 8; Queen queen = new Queen(); short[] cols = queen.getNewShort(n); // 初始化陣列, 存放列, 不能為預設值, 設定為2*n queen.putQueen(new short[n][n], (short) 0, cols, cols.clone(), cols.clone()); System.out.println(n + "皇后, 共 " + queen.list.size() + " 種情況, 用時: " + (System.currentTimeMillis() - currentTime) + "ms"); } private List<short[][]> list = new ArrayList<>(); /** * 遞迴存放皇后 * @param queens 歷史陣列 * @param c 當前第c個 * @param cols 以存放皇后的列序 * @param rowAddCols 行序+列序 * @param rowSubCols 行序-列序 */ private void putQueen(short[][] queens, short c, short[] cols, short[] rowAddCols, short[] rowSubCols) { for (short i = 0; i < queens.length; i++) { if (isContains(cols, i) || isContains(rowAddCols, (short) (c + i)) || isContains(rowSubCols, (short) (c - i))) { continue; } short[][] tqueens = copy(queens); short[] tcols = cols.clone(); short[] trowAddCols = rowAddCols.clone(); short[] trowSubCols = rowSubCols.clone(); tqueens[c][i] = 1; tcols[c] = i; trowAddCols[c] = (short) (c + i); trowSubCols[c] = (short) (c - i); if (c >= queens.length - 1) { list.add(tqueens); } else { putQueen(tqueens, (short) (c + 1), tcols, trowAddCols, trowSubCols); } } } // 判斷陣列中是否包含某元素 private boolean isContains(short[] array, short n) { for (short i : array) { if (i == n) { return true; } } return false; } // 初始化一個新的short陣列 private short[] getNewShort(int n) { short[] shorts = new short[n]; for (int i = 0; i < n; i++) { shorts[i] = (short) (2 * n); } return shorts; } // copy二維short陣列 private static short[][] copy(short[][] array) { short[][] result = new short[array.length][array[0].length]; for (int m = 0; m < array.length; m++) { for (int n = 0; n < array[0].length; n++) { result[m][n] = array[m][n]; } } return result; } }