赞
踩
下图有个简单的分析过程(图片来自网络)
check()
函数来实现这一点。sum
来记录解的数量,在每次找到一个合法的解时增加计数器。以下我将用代码演示解题的过程:
- int n; //表示要输入一个n*n的方格棋盘
- int column[12]; //表示列(题目中要求n的值最大为10,所以这里预留12个位置即可。多预留两个,防
- 止数组越界)
- //因为放置皇后时会按照从第一行依次向下第二、第三等行放置,所以对于“行”,直
- 接从1到n递增(row++)即可。
-
- int sum = 0; //记录合法的放置方式
-
- int check(int row) {
- for (int i = 1; i <= row - 1; i++) {
-
- //判断对角线上是否有皇后;(在对角线上:abs(行-行)==abs(列-列))
- if ((column[i] == column[row]) || abs(i - row) == abs(column[i] - column[row]))
- return 0; //不合法,返回0
- }
- return 1; //合法,返回1
-
- }
-
- void dfs(int row) {
-
- if (row == n + 1) { //结束条件(边界):如果当前“行”大于最后一行,即前n行全部放置完毕
-
- sum++; //放置方式+1
- return; //回溯(再去找前面的行,看是否还有其他位置可以选择)
- }
-
- for (int i = 1; i <= n; i++) { //从第一行开始遍历,一直到最后一行
-
- column[row] = i; //尝试将皇后放置在第row行的第i列
- if (check(row)) //检查放置的位置是否合法
- dfs(row + 1); //若合法,递归放置下一个皇后
- else
- continue; //不合法,跳过当前列
- }
- }
-
- int main() {
-
- cin >> n; //输入棋盘规模
-
- dfs(1); //从第一行开始进入
-
- cout << sum << endl;
-
- return 0;
- }

本体的困难点我个人认为:
一是在于:约束条件,包括不能在同一行、同一列或同一对角线上。要找到可以表示条件的关系,用(行-行)的绝对值==(列-列)的绝对值表示不在对角线的位置;
而是在于如何表示行与列,并确保每行每列的位置都能进行判断。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。