版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
在国际象棋中,皇后是最厉害的棋子,可以横走、直走,还可以斜走。棋手马克斯·贝瑟尔 1848 年提出著名的八皇后问题:即在 8 × 8 的棋盘上摆放八个皇后,使其不能互相攻击 —— 即任意两个皇后都不能处于同一行、同一列或同一条斜线上。
现在我们把棋盘扩展到 n × n 的棋盘上摆放 n 个皇后,请问该怎么摆?请编写程序,输入正整数 n,输出全部摆法(棋盘格子空白处显示句点“.”,皇后处显示字母“Q”,每两格之间空一格)。
时间限制: 20 ms
内存限制: 64 MB
代码长度限制: 16 KB
输入格式
正整数 n (0 < n ≤ 12)
输出格式
若问题有解,则输出全部摆法(两种摆法之间空一行),否则输出 None。
要求:试探的顺序逐行从左往右的顺序进行,请参看输出样例2。
输入样例1
3
输出样例1
None
输入样例2
6
输出样例2
. Q . . . .
. . . Q . .
. . . . . Q
Q . . . . .
. . Q . . .
. . . . Q .
. . Q . . .
. . . . . Q
. Q . . . .
. . . . Q .
Q . . . . .
. . . Q . .
. . . Q . .
Q . . . . .
. . . . Q .
. Q . . . .
. . . . . Q
. . Q . . .
. . . . Q .
. . Q . . .
Q . . . . .
. . . . . Q
. . . Q . .
. Q . . . .
代码如下(未经严格测试,不保证100%正确):
import java.util.*;
class Q { //皇后类
int x,y;
public Q(int x, int y) {
this.x = x;
this.y = y;
}
}
public class Main {
static int n;
static int[][] chressBoard;
static ArrayList<Q> list = new ArrayList<Q>(); //用于存放每个皇后的位置
static boolean Flag = true;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
chressBoard = new int[n][n];
recursion(0,1, chressBoard);
if(Flag)
System.out.println("None");
}
public static void recursion(int x, int count, int[][] chressBoard) {
for(int y=0;y<n;y++) {
if(chressBoard[x][y] == 0) {
if(list.isEmpty()) {
chressBoard[x][y] = 1;//标记皇后的位置为1。
list.add(new Q(x,y));
}
else {
boolean flag = true;
for(int i=0,size=list.size();i<size;i++) {
Q tmp = list.get(i);
//判断任意两个皇后都不能处于同一行、同一列或同一条斜线上
if(tmp.x==x || tmp.y==y || (Math.abs(tmp.x-x)==Math.abs(tmp.y-y)))
flag = false;
}
if(flag) {
chressBoard[x][y] = 1; //标记皇后的位置为1。
list.add(new Q(x,y));
}
else
continue;
}
if(x<n-1) {
recursion(x+1, count+1, chressBoard);
}
if(count == n) { //存在解
Flag = false;
//将结果输出
for(int i=0;i<n;i++) {
for(int j=0;j<n;j++) {
if(chressBoard[i][j]==1) {
if(j<n-1)
System.out.print("Q");
else
System.out.print("Q ");
}
else {
if(j<n-1)
System.out.print(".");
else
System.out.print(". ");
}
}
System.out.println();
}
System.out.println();
}
chressBoard[x][y] = 0; //还原对皇后位置在图中的标记为0
list.remove(list.size()-1); //在list中删除对皇后的标记
}
}
}
}
这次只提供代码,不保证代码的完全正确性,因为在PTA中无法提交。原因:题目限制的运行时间是20ms,我凌乱了,我再怎么优化我感觉这代码也到不了20ms以内啊,没办法,放弃治疗了。仅测试了当n=4、6、8时得到的结果均正确,其他的数据个人感觉应该也差不多,如果有问题希望大家能告诉我,我再修改代码。
简化版写法,同学的博客:https://blog.csdn.net/beilunc7/article/details/88357874