八皇后(Python)
实现思路
以皇后的为中心的上下左右和斜线方向都不能存在棋子;因此每一行只能存在一颗棋子;按行进行迭代即可。
首先定义一些全局变量;
q_list = [] # 皇后列表
answer_count = 0 # 答案计数参数
y = 0 # 当前行数
我们用一个列表来存放放置的皇后坐标,y为当前遍历的行数,初始值从第一行开始;
然后我们需要在列表中添加棋子;
第一步:获取当前行可以添加的棋子位置
寻找一般规律:假设在(0,0),(4,1)处已经有了棋子,继续遍历第三行的时候可以放置棋子的坐标怎么计算呢?在这里我们只需要获得x坐标即可。很明显通过皇后特点,左右上下斜方不能放,对于(0,0)来说,(0,2)(0+2,2)不能放,而对于(4,1)来说(4-1,2),(4,2),(4+1,2)不能放,于是我们找个规律:
def get_x_list(q_list):
x_list = list(range(8)) #0-7的列表
length = len(q_list) #皇后列表的长度
remove_list=[] #删除列表
#遍历皇后列表
for q in q_list:
x = q[0] #获取皇后横坐标
remove_list.append(x) #竖直方向横坐标
if x - length>=0:
remove_list.append(x-length) #斜左下
if q[0] +length< 8:
remove_list.append(x+length) #斜左下
length-=1 #下一个皇后往下靠了一行,参数要自减1
x_list=list(set(x_list)-set(remove_list)) #集合求差集
return x_list
于是我们可以得到在上一行放置基础上,下一行能放置皇后的位置。
接下来是重头戏,获取棋子,按行迭代
#判断下一行是否能放置棋子
def cof_next_q(y):
if y > 7:
return 1
x_list = get_x_list(q_list)
if len(x_list) == 0:
return -1
else:
return 0
#去除该行之后包括该行的棋子
def list_remove(y):
new_list = []
for i in q_list:
if i[1] 》= y:
new_list.append(i)
q_list=list(set(q_list)-set(new_list )) #集合求差集
#打印结果
def show_anwer(my_list):
global answer_count
anwer = [[0] * 8 for _ in range(8)]
for a in my_list:
y = a[0]
x = a[1]
anwer[y][x] = 1
answer_count += 1
print("第{}组答案:".format(answer_count))
for i in anwer:
print(i)
#获取棋子
def get_next_q(y):
# 获取当前行可填充的棋子位
x_list = get_x_list(q_list)
# 遍历该行棋子位
for x in x_list:
# 删除之前列表中该行之后包括该行的棋子
list_remove(y)
# 在该行添加一颗棋子
q_list.append((x, y))
# 判断下一行是否有可填充的棋子位 1:已到最后一行 0:存在 -1:不存在
conf_next = cof_next_q(y + 1)
# 遍历到最后一行
if conf_next == 1:
#打印结果
show_anwer(q_list)
# 递归调用 在下一行添加棋子
elif conf_next == 0:
get_next_q(y + 1)
# 继续循环 遍历该行棋子
else:
continue
最后写个main调用就行啦
if __name__ == '__main__':
q_list = [] # 皇后列表
answer_count = 0 # 答案计数参数
y = 0 # 当前行数
get_next_q(y)
判断那里还能改进,第一次这个东西写也不咋会,,,,,,,,
后面慢慢学吧,这也不是最简单的方法,只是自己琢磨出来了而已,,,,,