算法基础:n皇后问题
最近没有怎么读论文学新东西主要因为最近一直在写毕业论文。好消息是这周已经把毕业论文初稿基本写完了,差不多下周就能完成毕业论文了。论文写的差不多的话下个月我准备每周按时更新博客啦,同时下周5.1也是打算先回个家,然后回学校喽!所以本周我就水一篇我之前写的算法题-n皇后问题的题解。
问题介绍
n−皇后问题是指将 n 个皇后放在 n×n 的国际象棋棋盘上,使得皇后不能相互攻击到,即任意两个皇后都不能处于同一行、同一列或同一斜线上。
现在给定整数 n,请你输出所有的满足条件的棋子摆法。
输入格式
共一行,包含整数 n。
输出格式
每个解决方案占 n 行,每行输出一个长度为 n 的字符串,用来表示完整的棋盘状态。
其中 .
表示某一个位置的方格状态为空,Q
表示某一个位置的方格上摆着皇后。
每个方案输出完成后,输出一个空行。 注意:行末不能有多余空格。
输出方案的顺序任意,只要不重复且没有遗漏即可。
数据范围
1≤n≤9
输入样例:
plaintext
1 | 4 |
输出样例:
plaintext
1 | .Q.. |
题解
题目种最重要的信息:任意两个皇后都不能处于同一行、同一列或同一斜线上
这道题该如何思考呢?
本质上,n 皇后问题是一个典型的回溯问题:
- 每一行放一个皇后,在放之前判断当前位置是否被其他皇后攻击(即列、对角线、反对角线有没有冲突)。
- 如果当前位置安全,放置皇后,并递归到下一行。
- 如果递归返回(回溯),需要撤销当前放置,继续尝试其他位置。
我感觉这个代码写n-皇后问题实在是太简洁了,所以忍不住让人分享出来。
建议结合代码和这段描述一起看哦~
棋盘表示:
- 使用一个二维字符数组
s[N][N]
表示棋盘。 'Q'
表示皇后,'.'
表示空位。
辅助数组:
col[i]
:记录第i
列是否有皇后。dg[i]
:记录正对角线(↙)是否有皇后。编号方法是行号 + 列号
。udg[i]
:记录反对角线(↘)是否有皇后。编号方法是行号 - 列号 + n
(加n
保证下标非负)。
可能这里你会不明白为什么dg和udg数组大小定义2N?还有为什么编号方法是这样?

DFS递归:
dfs(level)
表示当前正在处理第level
行。- 如果
level == n
,说明所有行都放置完毕,输出当前棋盘。 - 否则,遍历当前行的每一列,尝试放置皇后。
完整代码:
cpp
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 SukiAme の Blog!