首页 > 试题广场 >

八皇后问题

[编程题]八皇后问题
  • 热度指数:219 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
八皇后问题,是一个古老而著名的问题。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。利用回溯算法我们能很快的得到共有92种互不相同的解(独立解有12种)。当棋盘变成n行,n列,且皇后也有n个的时候(n<=20),问有多少种不同的解?

输入描述:
一行,一个正整数n(1<=n<=20)


输出描述:
输出一个整数,代表解的个数。
示例1

输入

8

输出

92
示例2

输入

20

输出

39029188884

备注:
一般的回溯算法只能通过n<=13左右,以下给出n=14到20的答案。

对于想挑战原规模的选手请忽略以下答案。

365596, 2279184, 14772512, 95815104, 666090624, 4968057848, 39029188884
#栈代替递归
#木大木大,该超时还是超时...

n=int(input())
A, ans=[-1], 0                              # 初始list,第n个元素为i,代表第n行第i列,注释中假设以最下面为第0行
while len(A):                               # list空后结束,即第一行(第0行)所有列的所有可能都已搜索完毕了
    for A[-1] in range(A[-1]+1,n):          # list中最后一个数字,即循环到的最高一行的列数继续递增
        for row in range(len(A)-1):         # 这一行和下面一行用来检测纵横斜有没有皇后
            if A[row] == A[-1] or abs(A[-1] - A[row]) == len(A) - 1 - row: break    # 有皇后break弹出(即不是成功循环结束,不运行循环结束的代码块)
        else:                               # 如果循环成功没有皇后
            if len(A)==n: ans+=1             # 如果达到n层就输出
            else: A += [-1]; break          # 没达到则把A往上加一行,break弹出(即不是成功循环结束,不运行循环结束的代码块),加的最上面一行开始寻找
    else: A.pop()                           # 该行的列数成功循环到上限,就把这行pop掉,在次行继续搜索
print(ans)


发表于 2019-09-08 21:35:03 回复(0)