文章目录
8皇后问题
一、题目?
蓝桥杯省赛(中级)-第6题
八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
二、解题思路
1. 如何判定递归结束:
当递归到当前行==n 时,则表示前面的都已经判断好了。
1. 1 判定单元格里面可以放置皇后的方法:
1. 2 判定对应列是否可以放置皇后,如下图所示:
2. 代码示例
第一种方法:递归回溯
'''
_*_ coding: utf-8 _*_
@File : 八皇后 回溯.py
@Version : 1.0
@Author : Solar Lee
@Time : 2021/05/14 15:49:29
Description: Eight Queens problem solution.
'''
import time
def dfs(k):
global nums # 统计解法数量
if k == n: # 当递归到第n行时说明问题已经解决。
nums += 1 # 每当解出一种解法, 自增1.
[print('.'*i + 'Q' + '.' * (n - i - 1)) for i in row] + [print('')] #将解法打印出来。
return
for i in range(n):
if col_unused[i] and dg[i + k] and ndg[n + i - k]:
# 保存第k列皇后的位置。
row[k] = i
# 将当前列的变为已探测
col_unused[i] = dg[i + k] = ndg[n + i - k] = False
dfs(k + 1) # 进入下次递归
col_unused[i] = dg[i + k] = ndg[n + i - k] = True
def main():
dfs(0) # 从第0 行开始递归
print(nums)
if __name__ == '__main__':
nums = 0
n = int(input(请输入皇后个数: ))
dg, ndg, col_unused = [True] * (n << 1), [True] * (n << 1), [True] * n
row = [None] * n
start_time = time.time()
main()
end_time = time.time()
print(end_time-start_time)
第二种方法:递归
"""
# -*- coding: utf-8 -*-
Created on Tue Jun 8 22:07:41 2021
@ Author: solar.lee
@ Email: solar.lee@ii-vi.com.
Description:
To solve eight queens problem.
"""
def eight_queens(n):
'''
Parameters
----------
n : int
n*n array line to put n queen in it.
Returns
-------
None.
'''
line = [0]*n # 表示初始列表,确定目前棋盘的情况。
f(line,0,n) # 从第0行开始放皇后递归。
def f(line,m,n): # 递归函数
'''
Parameters
----------
line : list
current line data.
m int:
current line.
n int:
queen number.
Returns None.
'''
global count
if m == n: #递归边界这个要特别注意。
count += 1
print(line)
return
current_line = [True]*n #确认当前行的位置是否可以放置。初始化当前行状态。
for i in range(m):
current_line[line[i]] = False # 只要对应列有皇后,则对应列就不能放置了,即赋值为false。
k = m - i # 只要对应列有皇后,则对应斜线就不能放置了。
if line[i]+k<n: #右斜线
current_line[line[i]+k] = False
if line[i]-k>=0: # 左斜线
current_line[line[i]-k] = False
for i in range(n): # 遍历当前行的状态如果有True,则放入line[m],并确认对应的皇后的位置i
if current_line[i]:
line[m]=i
f(line,m+1,n) # 递归往下一列。
if __name__ == "__main__":
count = 0
queens_quantity = int(input('请输入皇后的个数: '))
eight_queens(queens_quantity)
print (count)
3.输出数据:
输入:8
输出:92种
输入:7
输出:40种
输入:4
输出:2种
总结
两种方法各有特点大家多思考下看看有没有更好的方法来解决!