n皇后(回溯和剪枝)--HDU2553

问题简介:

在棋盘上放置8个皇后,使它们不同行,不同列,不同对角线。问有多少种合法的情况?
N皇后问题是8皇后问题的扩展。

文章目录

    • 问题简介:
    • Key1
        • 如何递归?
    • Key2
        • 如何剪枝?

n皇后(回溯和剪枝)--HDU2553_第1张图片
n皇后(回溯和剪枝)--HDU2553_第2张图片
其实n皇后问题就是对所有的皇后进行枚举,我们采用递归的写法,其中有两个技巧就是回溯和剪枝。当我们发现当前情况已经不满足时,可以将这棵搜索树直接在此处剪短,然后回溯到上一个结点,继续进行枚举。

Key1

如何递归?

每一行放置一个皇后

void dfs(int r)  // 一行一行的放置皇后,本次在第r行开始
// r是从0开始计数的
{
     
    if (r == n) {
      // 所有皇后都放置好了之后, 递归返回
        ans++;	// ans记录合法的棋局个数
        return ;
    }
    for (int i = 0; i < n; i++) {
     
        queen[r] = i; // 在第r行的c列放置皇后
        if (check(r, queen[r])) {
      // 检查是否合法
            dfs(r + 1); // 继续放下一行皇后
        }
    }
}

Key2

如何剪枝?

  • 设左上角是原点(0, 0)
  • 已经防止好的皇后的坐标是(i, j)
  • 新皇后的坐标是(r, c)

原皇后(i, j), 新皇后(r, c)
(1) 横向,不同行: i != r
(2) 纵向,不同列: j != c
(3)斜对角,从(i, j)向斜对角走a步,走到新坐标(r, c)有以下四种情况。

  • 左上角: (i - a, j - a)
  • 右上角: (i + a, j - a)
  • 左下角: (i - a, j + 1)
  • 右下角: (i + a, j + a)
bool check(int r, int c)
{
     
    for (int i = 0; i < r; i++) {
     
        if (queen[i] == c || abs(queen[i] - c) == abs(i - r))
        // 检查同列, 同一对角线是否冲突
            return false;
    }
    return true;
}

复杂度分析dfs()一行行的放置皇后,复杂度O(n!)
check()冲突检查O(n)
总的复杂度O(n x n!)

HDU–2553代码如下:

#include 
using namespace std;
const int maxr = 10;
int n, ans;
int queen[maxr];

bool check(int r, int c)
{
     
    for (int i = 0; i < r; i++) {
     
        if (queen[i] == c || abs(queen[i] - c) == abs(i - r))
            return false;
    }
    return true;
}


void dfs(int r)
{
     
    if (r == n) {
     
        ans++;
        return ;
    }
    for (int i = 0; i < n; i++) {
     
        queen[r] = i;
        if (check(r, queen[r])) {
     
            dfs(r + 1);
        }
    }
}



int main()
{
     
    int res[maxr];
    for (int i = 0; i < maxr; i++) {
     
        memset(queen, 0, sizeof queen);
        ans = 0;
        n = i + 1;
        dfs(0);
        res[i] = ans;
    }
    while (cin >> n) {
     
        if (0 == n) break;
        cout << res[n - 1] << endl;
    }
    return 0;
}

采用另一种数据结构Dancing links可以解决15皇后的规模,详细介绍见以下博客:

你可能感兴趣的:(dfs)