7-2 N 皇后问题

7-2 N 皇后问题

分数 30

全屏浏览

切换布局

作者 usx程序设计类课程组

单位 绍兴文理学院

要求在n*n格的棋盘上放置彼此不会相互攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。

输入格式:

测试数据有多组,处理到文件尾。对于每组测试,输入棋盘的大小n(1<n<12)。

输出格式:

对于每组测试,输出满足要求的方案个数。

输入样例:

4

输出样例:

2

代码长度限制

16 KB

Python (python3)

时间限制

4000 ms

内存限制

64 MB

其他编译器

时间限制

400 ms

内存限制

64 MB

栈限制

8192 KB

解题思路:

一、问题分析:

1.N个皇后需要放在N×N的棋盘上

2.皇后不能在同一行、同一列或同一斜线上

3.需要计算所有可能的解法数量

二、使用回溯法的原因:

1.需要尝试所有可能的放置方式

2.当发现冲突时可以及时回退

3.适合解决排列组合类问题

三、 核心函数说明:

 # 检查位置是否安全
   def is_safe(board, row, col, n):
       # 检查三个方向:
       # 1. 同列
       # 2. 左上对角线
       # 3. 右上对角线
   
   # 回溯函数
   def backtrack(board, row):
       # 基本情况:到达最后一行
       # 递归情况:尝试在当前行的每一列放置皇后

 

四、算法步骤:

1.从第一行开始,逐行放置皇后

2.对每一行,尝试在每一列放置皇后

3.检查放置位置是否安全

4.如果安全,继续处理下一行

5.如果不安全或需要回溯,移除皇后并尝试下一个位置

时间复杂度:

  • O(N!),其中N是棋盘大小
  • 实际运行时间会因为剪枝而小于这个上限

空间复杂度:

  • O(N²),需要N×N的棋盘数组

完整代码展示

def is_safe(board, row, col, n):
    # 检查同一列
    for i in range(row):
        if board[i][col] == 1:
            return False
            
    # 检查左上对角线
    for i, j in zip(range(row-1, -1, -1), range(col-1, -1, -1)):
        if board[i][j] == 1:
            return False
            
    # 检查右上对角线
    for i, j in zip(range(row-1, -1, -1), range(col+1, n)):
        if board[i][j] == 1:
            return False
            
    return True

def solve_n_queens(n):
    def backtrack(board, row):
        # 如果已经放置了n个皇后,找到一个解
        if row == n:
            return 1
            
        count = 0
        # 尝试在当前行的每一列放置皇后
        for col in range(n):
            if is_safe(board, row, col, n):
                # 放置皇后
                board[row][col] = 1
                # 继续处理下一行
                count += backtrack(board, row + 1)
                # 回溯,移除皇后
                board[row][col] = 0
                
        return count

    # 创建n*n的棋盘
    board = [[0 for _ in range(n)] for _ in range(n)]
    return backtrack(board, 0)

def main():
    try:
        while True:
            n = int(input())
            if n < 1 or n > 11:  # 根据题目限制 1<n<12
                break
            result = solve_n_queens(n)
            print(result)
    except EOFError:
        pass

if __name__ == "__main__":
    main()

 运行截图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值