问题描述:给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?n小于等于8。
输入格式:输入的第一行为一个整数n,表示棋盘的大小。接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,表示对应的位置不可以放皇后。
输出格式:输出一个整数,表示总共有多少种放法。
样例输入:
4
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
样例输出:2
样例输入:
4
1 0 1 1
1 1 1 1
1 1 1 1
1 1 1 1
样例输出:0
这是问题描述
看到问题,读完一遍,有点懵逼,遇到这种读一遍不懂的问题一定冷静下来要多读几遍。对于此问题我们可以先放一个皇后,再放另外一个皇后,并且用不同数字代表不同皇后,这里用2代表黑皇后,3代表白皇后。先放置黑皇后。
因为每行都不能有相同皇后,所以放一个皇后后,就要跳到下一行,跳到下一行后要判断该行是否为最后一行,如果是,则判断是黑皇后放完还是白皇后放完。如果是黑皇后放完,则接着放白皇后,如果白皇后放完,则计数器num加一。如果不是最后一行,执行后续代码,在不是1的位置判断是否可以放皇后。代码中s代表当前放的皇后,chess是棋盘,放置皇后方法用lay()函数封装起来了。代码如下:
def lay(row, n, s, chess): # 放置皇后的函数
global num
if row == n: # 判断是否每行都遍历了
if s == 2: # s=2表示黑皇后,s=3表示白皇后
lay(0, n, 3, chess) # 黑皇后放完开始放白皇后
if s == 3: # 白皇后也放完,计数器加一
num += 1
return
for i in range(n):
if chess[row][i] != 1: # 棋盘位置不等于1表示不能放皇后或者位置被皇后占用
continue
if check(row, i, s, chess): # 判断列和对角线是否有相同皇后
chess[row][i] = s
lay(row + 1, n, s, chess) # 遍历下一行
chess[row][i] = 1
因为每列和对角线上也不能有相同皇后,所以需要检查一下每列和对角线上是否有相同皇后。这个方法用check()函数封装起来了。代码如下:
def check(row, i, s, chess):
h = row - 1 # h,l分别是行和列
l = i - 1
for m in range(row-1,-1,-1): # 判断同一列是否有相同皇后
if chess[m][i] == s:
return False
while h>=0 and l>=0: # 判断左上方对角线是否有相同皇后
if chess[h][l] == s:
return False
h -= 1
l -= 1
h = row - 1
l = i + 1
while h>=0 and l<n: # 判断右上方对角线是否有相同皇后
if chess[h][l] == s:
return False
h -= 1
l += 1
return True
然后把代码整合起来就行了。代码如下:
n = int(input())
chess = [list(map(int,input().split(' ')))for i in range(n)] # 模拟棋盘
num = 0
def lay(row, n, s, chess): # 放置皇后的函数
global num
if row == n: # 判断是否每行都遍历了
if s == 2: # s=2表示黑皇后,s=3表示白皇后
lay(0, n, 3, chess) # 黑皇后放完开始放白皇后
if s == 3: # 白皇后也放完,计数器加一
num += 1
return
for i in range(n):
if chess[row][i] != 1: # 棋盘位置不等于1表示不能放皇后或者位置被皇后占用
continue
if check(row, i, s, chess): # 判断列和对角线是否有相同皇后
chess[row][i] = s
lay(row + 1, n, s, chess) # 遍历下一行
chess[row][i] = 1
def check(row, i, s, chess):
h = row - 1 # h,l分别是行和列
l = i - 1
for m in range(row-1,-1,-1): # 判断同一列是否有相同皇后
if chess[m][i] == s:
return False
while h>=0 and l>=0: # 判断左上方对角线是否有相同皇后
if chess[h][l] == s:
return False
h -= 1
l -= 1
h = row - 1
l = i + 1
while h>=0 and l<n: # 判断右上方对角线是否有相同皇后
if chess[h][l] == s:
return False
h -= 1
l += 1
return True
lay(0, n, 2, chess)
print(num)
运行结果:
点赞支持一下呗