⼋皇后问题描述
国际象棋8*8棋盘,64个位置,放8个皇后,皇后可以横竖斜线吃⼦,因此每个皇后所在的⾏、列和斜线都不能放皇后。 ⼩于5*5的棋盘⽆法每⾏放⼀个皇后,因此从五皇后以上可解N皇后问题。
8*8棋盘⽤⼆位数据表⽰,初始全部为0,落⼦的位置改为1.
allow_luozi函数判断某个位置是否可以落⼦,对于⼀个待判断的位置(x, y),如果以下位置都没有皇后,则可以落⼦:
1. 它上⾯每⼀⾏的y列位置
2. 它的左上斜线的每个位置
大型风力发电机组
3. 它的右上斜线的每个位置
eight_quene函数递归从左上⾓开始逐⾏尝试落⼦,每⼀⾏从左到右尝试,因此allow_luozi函数只需要判断当前位置的上、左上和右上三条线。如果⼀个位置可以落⼦,就落⼦然后在下⼀⾏落⼦。 如果⼀⾏没有位置可以落⼦,就向上回溯,把上⼀⾏的皇后从它的位置改到下⼀个可以落⼦的位置。当落⼦位置在最底下⼀⾏时,就到了⼀个解,将它打印出来。然后把最底下⼀⾏的皇后拿⾛,向上回溯,将上⼀⾏的皇后改到下⼀个可以落⼦的位置。这样通过不断的递归和回溯到全部解。
代码
count = 0
board = [[0for _ in range(n)] for _ in range(n)]
def allow_luozi(x, y):
if any([board[i][y] for i in range(x)]) \
or any([board[x-i][y-i] for i in range(1, n) if x - i >= 0and y - i >= 0]) \
or any([board[x - i][y + i] for i in range(1, n) if x - i >= 0and y + i < n]):
return False
else:
return True
tek-081def eight_quene(x=0, y=0):
if y == n:
if x == 0:
print('finished')
return
else:
x -= 1
y = board[x].index(1)
board[x][y] = 0
eight_quene(x, y+1)
else:
if allow_luozi(x, y):
board[x][y] = 1
if x == n - 1:
global count
count += 1
print(count)
for line in board:
print(line)
print()
board[x][y] = 0
x -= 1
y = board[x].index(1)
board[x][y] = 0
eight_quene(x, y+1)
else:
eight_quene(x+1, 0)
else:
eight_quene(x, y+1)
程序执⾏遇到的问题
六皇后以上运⾏程序报错:
RecursionError: maximum recursion depth exceeded in comparison
递归深度超过限制了,这时候问谁最好使?——stackoverflow啊,弄不好⽹站就是因为这个问题得名的。python递归栈有限制,可以通过设置调⼤。
import sys
sys.setrecursionlimit(100000)
这样执⾏不报错了,但是仍然不能执⾏完,有个负值的退出码:
Process finished with exit code -1073741571 (0xC00000FD)
[0, 0, 0, 0, 0, 0, 0, 1]
[0, 0, 1, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 1, 0, 0]
功夫杯
[0, 1, 0, 0, 0, 0, 0, 0]
ca185[0, 0, 0, 0, 1, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 1, 0]
[0, 0, 0, 1, 0, 0, 0, 0]
鼠标笔
()
92
移动终端安全
[0, 0, 0, 0, 0, 0, 0, 1]
[0, 0, 0, 1, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 1, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 1, 0, 0]
[0, 1, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 1, 0]
[0, 0, 0, 0, 1, 0, 0, 0]
()
我在windows的虚拟机和ubuntu⼦系统上执⾏都是只能输出前90种解法,可能跟操作系统还是有关系。5-8皇后的摆法
五皇后10种
六皇后4种
七皇后40种
⼋皇后92种