[vip蓝桥杯]--2n皇后的python解法 ,比较容易理解

题目描述
给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?n小于等于8。
输入
输入的第一行为一个整数n,表示棋盘的大小。 n小于等于8
接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,表示对应的位置不可以放皇后。 
输出
输出一个整数,表示总共有多少种放法


思路

先放白皇后再放黑皇后

其实本质是利用回溯,回溯的基本模板:

void backtracking(参数) {
 if (终⽌条件) {
 存放结果;
 return;
 }
 for (选择:本层集合中元素(树中节点孩⼦的数量就是集合的⼤⼩)) {
 处理节点;
 backtracking(路径,选择列表); // 递归
 回溯,撤销处理结果
 }
}
n = int(input())
a = []
for i in range(n):
    a.append(list(map(int,input().split())))   #创建二维数组

count = 0   #记次数
def brak(row,n,s,a):
    global count     #要设为全局变量,不然就会为0
    if row == n:   #判断是否放到最后一行
        if s ==2 :    #白皇后放完了,就放黑皇后
            brak(0,n,3,a)
        if s ==3:   #黑皇后也放完了
            count = count+1
        return  

    for i in range(n):
        if a[row][i] != 1: #不是1证明这里不能放皇后,顺便判断同行有没有皇后
             continue
        if check(row,i,s,a): #row,i横列坐标,s白皇后还是黑皇后,a数组
            a[row][i]=s
            brak(row+1,n,s,a)
            a[row][i]=1

def check(row,i,s,a):
    for j in range(row-1,-1,-1):
        if a[j][i]==s: #判断同列是否有皇后
            return False

    r,c = row-1,i-1
    while r>=0 and c>=0:    #检查左上角
        if a[r][c]==s:
            return False
        r,c = r-1,c-1    #应该要自己递减,而不是靠row,i来减一

    r,c = row-1,i+1
    while r>=0 and c<n:    #检查右上角,c的条件没有判断好,不能c>=0
        if a[r][c]==s:
            return False
        r,c = r-1,c+1
    return True

brak(0,n,2,a)
print(count)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值