2n皇后问题 蓝桥杯 详细注释

2n皇后问题
大致题意: 两个n皇后问题
大致思路:
递归回溯:当前行中有一位置如果能放棋子,则放,然后考虑下一行,不管最后结果怎么样,都要把当前位置放的棋子收回,考虑当前行中的下一个位置,最终得以考虑所有情况。
先采用递归回溯,去求解一个n皇后问题(黑)。当n皇后(黑)求解完成,从头开始遍历数组,再求解一个n皇后问题(白)。
利用取模运算的方法来对问题进行简化,即行数<n(输入的规格)时,在求解黑皇后;当行数>=n时,在求解白皇后,并用real_row = row % n 来表示实际的行数。
整个棋盘里(二维数组),0表示不能放、1表示空闲可以放、2表示已经放了黑棋、3表示已经放了白棋。
其他东西都写在注释里了。
代码+详细注释:

# 2*n queens
def solve(row): # 传入一个行数就够了,map_lst 是可变数组,可以直接修改之,计数的ans设置为全局变量,列数每一次都要从0访问到n-1
    global ans
    if row == 2*n:
        ans += 1
        return 0  # return几无所谓,我们只是想要计数,计完数停止
    if row < n:  # 如果放黑棋
        put_in = 2
    else:
        put_in = 3
    real_row = row%n  # 下面用real_row来进行访问
    for tmp_col in range(0,n):  #  当前行,所有列都要考虑
        if is_place(row,tmp_col):  # 如果可以放,就放
            map_lst[real_row][tmp_col] = put_in
            solve(row+1)  # 放完,进行递归,考虑下一行
            map_lst[real_row][tmp_col] = 1  # 上一层递归要么摆放成功,ans加 1;要么不成功,不用操作,直接return停止。不管是那种情况
                                            # 我们都要回溯,继续考虑这一行中的下一个
    return 0  # 结束
    
def is_place(row,col): # row表示行,col表示列
    if row < n:  # 模为n,即如果放了前面0-n-1行(黑棋放好),row%n得0,从第0行开始放白棋
        judge_sign = 2 # 如果在放黑棋,而黑棋用2表示,所以接下来的判断标志设为2
    else:
        judge_sign = 3 # 否则为白棋
    # 白皇后黑皇后统称为棋子
    # 四种情况,1、当前位置能否放、有无别的棋子 2、当前列有无冲突 3、左上对角线 4、右上对角线
    row = row%n
    if map_lst[row][col] != 1:  # 可能等于0,也可能放了另一个颜色的棋子
        return False
    for tmp_row in range(row-1,-1,-1):  # 判断列
        if map_lst[tmp_row][col] == judge_sign:
            return False
    tmp_row = row - 1
    tmp_col = col - 1
    while tmp_row >= 0 and tmp_col >= 0:  # 判断左上对角线
        if map_lst[tmp_row][tmp_col] == judge_sign:
            return False
        tmp_row -= 1
        tmp_col -= 1
    tmp_row = row - 1
    tmp_col = col + 1
    while tmp_row >= 0 and tmp_col <= n-1:  # 判断右上对角线
        if map_lst[tmp_row][tmp_col] == judge_sign:
            return False
        tmp_row -= 1
        tmp_col += 1
    return True

if __name__ == "__main__":
    n = int(input())  # 输入的规格
    map_lst = []  # 地图
    for i in range(n):
        one_line = [int(j) for j in input().split()]
        map_lst.append(one_line)
    ans = 0  # 计数的答案
    solve(0)
    print(ans)
发布了45 篇原创文章 · 获赞 0 · 访问量 983

猜你喜欢

转载自blog.csdn.net/jokerxsy/article/details/104814118
今日推荐