算法设计四(4)——八皇后问题

算法分析与设计

时间

2020.6.6

 实验名称

Who needs 8 Queens when you can have N?

实验目的

通过在线实验,要求深度掌握n后问题的问题描述、算法设计思想、程序设计。

实验原理

利用n后问题构造法思想,根据题目所给出的条件,求解问题,计算出可行的皇后安排策略。

实验步骤

 问题描述:

【Description】

The N -Queens problem is an obvious expansion of the eight-queens problem that has been around for a long time: Given a board with N x N squares and N queens, position the queens on the board such that no two queens can attack each other; in other words, so that no two queens sit on the same horizontal row, vertical column, or along either possible diagonal (row+column = k for one, row-column = k for the other).

Finding all the solutions to the problem for a given N is known to be worse than exponential in difficulty -O(N!) . One can, however, find a single solution to the problem in significantly less time if one looks beyond the standard backtracking solution to another possible solution strategy.

This problem asks you to find such a solution strategy. Note that the solution found may not necessarily be the one obtained first in the backtracking approach.

Since there is a huge number of candidate solutions for any but the very smallest values of N , the judges have access to a solution validation program. Consequently it is critical that you abide by the output specifications, since they constitute the input specifications for the validator.

【Input】

The input file begins with a line containing a single integer (no white space) specifying the number of problem specifications in the file. Exactly that many lines follow, each giving the value of N (with no white space) for which you are to solve the N -queens problem. The values of N may range from 4 up through 300; in other words, you should be able to find some solution to the 300-Queens problem in less than 120 seconds.

【Output】

For each problem, output on a single line that number (N ). Following that, give the permutation vector of column positions (0 through N - 1 ) that specify the queen's position on each succeeding row. The permutation vector is to be of N integers separated by white space. You may choose for yourself whether you use simple blanks for white space (giving the solution vector on one line) or you put each value on a separate line. In the interest of printing, the sample output here will use an approach that generates lines of values that do not exceed 65 characters in length. You are not held to that format. Then, the sample output is one of a very large number of possible outputs.

【Sample Input】

 4

4

8

25

50

【Sample Output】

 4

 2 0 3 1

8

 2 7 3 6 0 5 1 4

25

 14 7 18 22 13 10 24 11 1 20 6 0 15 8 5 16 23 17 4 21 12 2 19 3 9

50

 22 13 15 44 27 3 1 4 19 40 20 5 31 49 7 29 18 6 2 36 28 12 38 43

 39 11 26 14 0 30 34 8 41 9 16 10 17 33 45 42 46 24 47 35 32 23

 问题分析:

   M皇后问题: 在M×M格的国际象棋上摆放M个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上。

  根据场景,又有三种衍生问题:

  ① 共有多少种摆法(即有多少种可行解)

  ② 求出所有可行解

  ③ 求任意一个可行解

问题① 属于 禁位排列 问题,目前是存在通项公式直接求解的。

  问题② 属于 搜索 问题,在网上也有多种解法,主流是 回溯法(另有衍生的位运算变种算法),但不管如何优化,回溯法都有一个致命的问题:M值不能过大(一般M=30已是极限)。

  问题③ 属于 问题② 的子集,因此很多人的切入点依然是回溯法,也有启发式算法的解法:如遗传算法、还有刘汝佳在《算法艺术与信息学竞赛》提出的启发式修补算法。启发式算法在M<10000左右都是可解的,但是因为启发式算法均存在随机性,收敛速度视不同的收敛因子而变化(我看过某篇论文称启发式算法在M=10000时的耗时等价于回溯法M=30的耗时)。

但早在1969年, 问题③ 的解就被E. J. Hoffman、J. C. Loessi 和R. C. Moore找到了潜在的数学规律,通过推导出数学公式,利用 构造法 使得该问题可在O(1) 的时间复杂度得到解

注:推导过于复杂,因此直接使用。

 算法思想:

   根据输入的n(0<n<300)按照构造法直接构造答案;

   构造法的公式如下:

算法步骤:

① 读入n;

② 判断n满足构造法的哪种情况

③ 按照构造法直接构造解

④ 输出该解,并判断是否处理结束,没有则回到①;

关键代码

关键代码(带注释)

按照构造法进行求解

 

构造法将n分为3种情况,①n mod 6 != 2 或 n mod 6 != 3 、②n mod 6 == 2 或 n mod 6 == 3(又分为n为奇数与偶数两种情况)

main函数

循环处理输入的n,并打印出构造法得到的数列;

测试结果

运行结果截图及分析

对于题目样例:

   

运行正确;

 对于测试数据

正确accept

时间复杂度分析:

 对每一个输入样例n来说,可以直接使用构造法进行答案构造,与输入的规模n无关,因此时间复杂度是O(1)的。

 空间复杂度分析:

 最少需要O(n)来存储解向量;

实验心得

这个问题从一开始的回溯法到现在的构造法,我只能感慨数学的强大,n后问题求1个解这样的有着规律的问题可以推导出数学公式来直接在O(1)内写出答案,而不需要再去用回溯法在O(n!)的时间内去查找。那么是不是还有很多的有复杂规律的问题也可以推导出他们的构造结构呢,我相信一定是可以的,有规律的问题最终都应该是可以像这道题一样可以写出构造公式的。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值