暴力回溯法 解八皇后
国际象棋
八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
public class _8Queen { //回溯法,暴力解8皇后 private static int ways = 0; //返回解法个数 public static int f8queen() { int[][] board = new int[8][8]; ways = 0; p_f8queen(board, 0); return ways; } private static void p_f8queen(int[][] board, int row) { if (row > 7) { ways++; printBoard(board); //最后一行穷举完,输出棋盘 return; } for (int col = 0; col < 8; col++) { if (check(board, row, col)) { //检测是否符合规则 board[row][col] = 1; //放皇后棋子 p_f8queen(board, row + 1);//进入下一行 board[row][col] = 0; //清除 } } } private static void printBoard(int[][] board) { for (int row = 0; row < 8; row++) { for (int col = 0; col < 8; col++) { if (board[row][col] != 1) System.out.print('.'); //.为棋盘空白格 else System.out.print('Q'); //Q为皇后棋子 } System.out.println(); } System.out.println("=============="); } private static boolean check(int[][] board, int row, int col) { for (int tmprow = row - 1; tmprow >= 0; tmprow--) { int l = col - (row - tmprow); int r = col + (row - tmprow); if (l > -1 && board[tmprow][l] != 0) //左上角线 return false; if (r < 8 && board[tmprow][r] != 0) //右上角线 return false; if (board[tmprow][col] != 0) //顶部线 return false; } return true; } public static void main(String[] ar) { System.out.println(f8queen()); } }
输出
Q....... ....Q... .......Q .....Q.. ..Q..... ......Q. .Q...... ...Q.... ============== 。。。。。。。。。(过多。。。。省略) ============== .......Q ...Q.... Q....... ..Q..... .....Q.. .Q...... ......Q. ....Q... ============== 92
可以看到穷举出了92种
其实还有基于图论的解法