八皇后问题(Java)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/l870358133/article/details/102532937

在国际象棋中,皇后是最厉害的棋子,可以横走、直走,还可以斜走。棋手马克斯·贝瑟尔 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

猜你喜欢

转载自blog.csdn.net/l870358133/article/details/102532937