问题描述

        给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?n小于等于8。


解题思路:

        本题有两个主要难点:(一)判断某个棋盘位置能否放置皇后。思路是通过对某一个位置的行标列标的增减,来访问它所在行所在列所在对角线的其它位置的元素,如果其它位置存在不为1的元素。则不能放置皇后;(二)模拟所有可能的放法,并找到成功放完所有皇后的放法,解决这一点需要用到递归函数(详细见代码)。

        本文定义了两个函数解决上述两个难点。

完整代码如下


# 2022.1.6
# 蓝桥杯基础练习
# 试题名称:2n皇后问题
# 问题描述:给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。
# 现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后
# 都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在
# 同一行、同一列或同一条对角线上。问总共有多少种放法?n小于等于8。# board是棋盘,row是二维列表的行标,col是列标,flag 是皇后的类型,2代表黑皇后,3代表白皇后
def able(board, row, col, flag):   # 此函数判断某位置是否能放置皇后a = rowb = colfor x in range(len(board)):    # 检查对应列if(board[x][col] == flag):return Falsewhile((a>=0) & (b>=0)):        # 检查左上角if(board[a][b] == flag):return Falsea -= 1b -= 1   a = rowb = colwhile((a>=0) & (b<=len(board)-1)): # 检查右上角if(board[a][b] == flag):return Falsea -= 1b += 1 return Truedef xiaqi(board, n, row, flag): # 递归函数:模拟所有放法。n是棋盘的行数global countif row == n:                # 当row=n时,说明放了一遍黑(白)皇后,要注意不一定能放完if flag == 2:xiaqi(board, n, 0, flag+1)if flag == 3:               # 放完黑皇后,再放白皇后#for x in range(n):#print(board[x])    # 打印输出放置成功的棋盘(题目不要求)#print()count += 1               for i in range(n):if row == n:continueif board[row][i] != 1:continueif board[row][i] == flag:continueif( able(board, row, i, flag) ):board[row][i] = flag         # 放皇后,并做标记,2代表黑皇后,3代表白皇后xiaqi(board, n, row+1, flag) # 在该递归分支中,放置下一行的皇后board[row][i] = 1            # 回溯count = 0                 # 放置成功数
n = int(input())
board = [list(map(int, input().split())) for i in range(n)]     # 获取棋盘
xiaqi(board, n, 0, 2)
print(count)

运行结果图:

打印输出放置成功的棋盘:

注:2代表黑皇后,3代表白皇后。


关于本题时间复杂度的问题:

在一开始,我定义了多个函数来判断棋盘位置是否能放置皇后,导致提交的代码因为超时不能得到100分,只有80多分,后来我将这多个函数写在一起变成一个函数后,问题成功解决了,代码不再超时,且得到了100分。

降低时间复杂度的一些方法:

1. 在不影响功能的前提下,尽可能地降低函数数量,因为调用函数需要花费时间。

2. 尽可能地减少循环的使用。

3. 学习更多的算法,减少使用暴力解题法

蓝桥杯基础练习 - 2n皇后问题解析相关推荐

  1. 蓝桥杯 基础练习 2n皇后

    目   录 题目描述 题解 [算法]八皇后,蓝桥杯2n皇后 算法思路详细讲解(Java) 题目描述 题目描述 给定一个 n × n 的棋盘,棋盘中有一些位置不能放皇后. 现在要向棋盘中放入 n 个黑皇 ...

  2. 蓝桥杯 基础练习 2n皇后问题(从n皇后问题入手)

    n皇后问题是一个以国际象棋为背景的问题:在n×n的国际象棋棋盘上放置n个皇后,使得任何一个皇后都无法直接吃掉其他的皇后,即任意两个皇后都不能处于同一条横行.纵行或斜线上. 利用递归和回溯算法轻松解决 ...

  3. 蓝桥杯 基础练习全解 答案+解析 共17题 python

    关键字 A+B问题,数列排序,十六进制转八进制,十六进制转十进制,十进制转十六进制,特殊回文数,回文数,特殊的数字,杨辉三角形,查找整数,数列特征,字母图形,01字串,闰年判断,斐波那契数列,圆的面积 ...

  4. 蓝桥杯基础练习所有VIP习题解析代码

    阶乘计算 资源限制 时间限制:1.0s 内存限制:512.0MB 问题描述 输入一个正整数n,输出n!的值. 其中n!=123*-*n. 算法描述 n!可能很大,而计算机能表示的整数范围有限,需要使用 ...

  5. 蓝桥杯算法提高----2n皇后

    2n皇后 问题描述 给定一个n*n的棋盘,棋盘中有一些位置不能放皇后.现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行.同一列或同一条对角线上,任意的两个白皇后都不在同一行.同 ...

  6. 十二届蓝桥杯省赛B组C++解析(填空题部分)

    十二届蓝桥杯省赛B组C++解析(填空题部分) 目录 十二届蓝桥杯省赛B组C++解析(填空题部分) A:空间 B:卡片 C:直线 D:货物摆放 E:路径 A:空间 该题是一道计算机基础原理题,这里需要了 ...

  7. 蓝桥杯基础-【切面条】不用画图的解题思路

    我们先来看[切面条]的题目: 一根高筋拉面,中间切一刀,可以得到2根面条. 如果先对折1次,中间切一刀,可以得到3根面条. 如果连续对折2次,中间切一刀,可以得到5根面条. 那么,连续对折10次,中间 ...

  8. 蓝桥杯基础视频 笔记

    学习地址:哔哩哔哩网站--蓝桥杯基础视频         博主整理--源码下载--百度网盘链接 蓝桥杯 Java B组 省赛真题详解及小结汇总[2013年(第4届)~2020年(第11届)] 注意:部 ...

  9. java蓝桥杯凑算是,第七届蓝桥杯JAVA B组真题解析-凑算式(第三题)

    第七届蓝桥杯JAVA B组真题解析-凑算式(第三题) 凑算式 A+B/C+DEF/GHI =10 (如果显示有问题,可以参见[图1.jpg]) 这个算式中AI代表19的数字,不同的字母代表不同的数字. ...

最新文章

  1. 算法_棋盘型高维动态规划
  2. R语言str_starts函数和str_ends函数检查在字符串的开头或者结尾是否存在特定字符串或者字符串模式
  3. Nature最新封面:两大数学难题被AI突破!DeepMind YYDS
  4. 从互联网大脑模型看腾讯与今日头条之争
  5. SoftGrid教程-注意事项、错误代码
  6. Scrapy学习篇(九)之文件与图片下载
  7. 软件项目管理0831:不要自我评价过高
  8. AndroidL的checkPermission方法详解
  9. js兼容注意事项--仅供参考
  10. C#8.0: 在 LINQ 中支持异步的 IAsyncEnumerableT接口
  11. UNDO Tablespace
  12. 以色列网络安全初创企业Cronus获350万美元A轮融资
  13. pythontkinter做计算器_Python Tkinter实现简易计算器功能
  14. SOTIF预期功能安全分析方法
  15. vs如何包含库文件以及头文件
  16. AutoResetEvent和ManualResetEvent的区别
  17. 常见电线电缆电阻的检测方法盘点
  18. Uncertainty Modeling and Optimization-不确定性建模与优化-理论篇(高速更新中)
  19. Pspice仿真实验 例B-1
  20. 网页的基本信息及组成HTML文件的基本结构

热门文章

  1. jenkins如何清缓存_空间清理jenkins,linux清理空间
  2. Adguard Home导致bilibili图片视频被屏蔽记录
  3. linux 命令行启动火狐,命令行安装firefox
  4. .Net强大的列表控件XPTable【进阶版】
  5. 自托管视频共享平台Clipable
  6. 用Python解析WinMerge生成的Patch文件
  7. 如何记账手把手教你轻松记账
  8. 02 Hexo博客Butterfly主题配置博客评论邮件提醒
  9. html5 pjax,关于PJAX局部刷新
  10. java正则字母下划线数字_由数字、26个英文字母、下划线或汉字的正则表达式