题目如下:
在国际象棋中,皇后是最厉害的棋子,可以横走、直走,还可以斜走。棋手马克斯·贝瑟尔 1848 年提出著名的八皇后问题:即在 8 × 8 的棋盘上摆放八个皇后,使其不能互相攻击 —— 即任意两个皇后都不能处于同一行、同一列或同一条斜线上。例如:
现在我们把棋盘扩展到 n×n 的棋盘上摆放 n 个皇后,请问该怎么摆?
请编写程序,输入正整数 n (n≤10),输出全部摆法。
要求:棋盘空白处显示句点“.”,皇后处显示字母“Q”,两个字符之间空一格,两种摆法之间空一行。
输入格式
正整数 n (n>0)
输出格式
若问题有解,则输出全部摆法。 若问题无解,则输出 None。
要求:试探的顺序按从上到下逐行进行,其中每一行按从左到右的逐格进行,请参看输出样例2。
输入样例1
3
输出样例1
None
输入样例2
4
输出样例2
. Q . .
. . . Q
Q . . .
. . Q .
. . Q .
Q . . .
. . . Q
. Q . .
解题思路:
八皇后问题是一个经典的回溯算法问题,目标是在n×n的棋盘上放置n个皇后,使得它们不能互相攻击,即任意两个皇后不能位于同一行、同一列或同一条斜线上。题目要求对于给定的正整数n(n≤10),找出所有可能的摆放方式,并以特定格式输出每种解法或者在无解时输出"None"。
解题思路主要采用回溯法,从棋盘的第一行开始逐行尝试放置皇后。对于每一行中的每一个位置,检查其是否满足不被其他已放置的皇后攻击的条件(不在相同的列以及两条对角线上)。如果当前位置可以放置皇后,则标记相应的列和对角线为“占用”,然后递归进入下一行继续尝试放置;若某次递归返回意味着后续行无法找到合适位置放置皇后,则撤销当前选择(即回溯),并尝试同一行的下一个位置。当成功放置了n个皇后(即到达了最后一行以下)时,记录或直接打印出一种解法。通过这种方式遍历所有可能的布局,找到所有的解法。如果没有找到任何解法,则最后输出"None"。
代码如下:
import java.util.Scanner;
public class Main {
static int n;
static int[] queens;
static boolean[] cols;
static boolean[] diag1;
static boolean[] diag2;
static boolean hasSolution = false;
static boolean firstSolution = true;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
n = scanner.nextInt();
if (n <= 0 || n > 10) {
System.out.println("None");
return;
}
queens = new int[n];
cols = new boolean[n];
diag1 = new boolean[2 * n - 1];
diag2 = new boolean[2 * n - 1];
solve(0);
if (!hasSolution) {
System.out.println("None");
}
}
static void solve(int row) {
if (row == n) {
printSolution();
hasSolution = true;
return;
}
for (int col = 0; col < n; col++) {
if (!cols[col] && !diag1[row + col] && !diag2[row - col + n - 1]) {
queens[row] = col;
cols[col] = true;
diag1[row + col] = true;
diag2[row - col + n - 1] = true;
solve(row + 1);
cols[col] = false;
diag1[row + col] = false;
diag2[row - col + n - 1] = false;
}
}
}
static void printSolution() {
if (!firstSolution) {
System.out.println();
}
firstSolution = false;
for (int i = 0; i < n; i++) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j < n; j++) {
if (queens[i] == j) {
sb.append("Q");
} else {
sb.append(".");
}
if (j < n - 1) {
sb.append(" ");
}
}
System.out.println(sb.toString());
}
}
}
提交结果如下:
答案正确