问题描述:n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。也就是说:存在一个N*N的棋盘,要放N个棋子,每个棋子不同行,不同列,不同(正反)对角线
算法设计:
回溯算法:
记录行,列, 正对角,负对角,不能有两个以上的棋子.
如何判断是否在对角上呢?
正对角就是相加之和一样的
负对角就是相减只差一样的
回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。
# n皇后问题
# 定义寻找函数
n=int(input())
place=[0 for i in range(n)] # 第几行放在第几列 说人话就是皇后放在第几行第几列 place[0]=1 表示第一行放在了第二列 place[1]=3 表示数第二行放在了第四列
print(place)
flag=[0 for i in range(n)] #表示第n列是否被标记 flag[1]=1
d1=[0 for i in range(n*2-1)] # d1[0+1]=1第一行第二列的对角线被标记了
d2=[0 for i in range(n*2-1)] # 表示下对角线啊是否被标记
count=0
def printf(place):
for i in range(n):
for j in range(n):
if place[i]==j:
print('*',end=' ')
else:
print("0",end=" ")
print()
print()
def search(row):
global count
for col in range(n):# 遍历每一行的每一列
# 对每一列的每个各自进行判断
if flag[col]==0 and d1[row+col]==0 and d2[row-col+n-1]==0:
place[row]=col
flag[col]=1
d1[row+col]=1
d2[row-col+n-1]=1
if row<n-1:
search(row+1)
else:
count+=1
printf(place)
flag[col]=0
d1[row+col]=0
d2[row-col+n-1]=0
return count
print(search(0))
这个方法没有用二维数组。
search函数
1.遍历矩阵每一行的每一列
2.判断皇后能否放置
放置条件:这一列、正对角线、反对角线都没有放置皇后
3.放置皇后
怎么放置:列和对角线初始化都是0,如果放置了皇后,他们都变成1
place[row]=col flag[col]=1 d1[row+col]=1 d2[row-col+n-1]=1
4.递归终止的条件
if row<n-1: search(row+1)
向函数中输入row的值为0,即从第一行开始遍历,直到遍历到最后一行