菜鸡的dfs学习 n-皇后问题

n-皇后问题(仅供菜鸡我自学)

题目描述

    n-皇后问题是指将 n 个皇后放在 n∗n 的国际象棋棋盘上,使得皇后不能相互攻击到,即任意两个皇后都不能处于同一行、同一列或同一斜线上。
现在给定整数n,请你输出所有的满足条件的棋子摆法。

Input

    共一行,包含整数n(n ≤ 10)。

Output

    每个解决方案占n行,每行输出一个长度为n的字符    串,用来表示完整的棋盘状态。
    其中”.”表示某一个位置的方格状态为空,”Q”表示某一个位置的方格上摆着皇后。
    每个方案输出完成后,输出一个空行。
    输出方案的顺序任意,只要不重复且没有遗漏即可。

分析

    根据题意,我们可以知道每一行和每一列有且只能有一个皇后,所以我们可以用dfs枚举每一行或每一列,假定我们从0开始枚举行,那么我们可以设置三个bool数组 col、d、ud 分别表示当前位置所在列、对角线和反对角线上是否有皇后。
    接下来让我们来看一下如何快速的判断两条对角线上是否有皇后,我们以棋盘的左、上边界建立直角坐标系,如图,我们可以用截距(b > 0)来唯一表示一条对角线
在这里插入图片描述

代码

#include<iostream>

using namespace std;
const int N = 10;
char a[N][N];
int n;
bool col[N], d[N * N], ud[N * N];
void dfs(int x) {
    if(x == n) {
        for(int i = 0; i < n; i ++) puts(a[i]);
        puts("");
        return ;
    }
    //从每一行第一个开始搜
    for(int i = 0; i < n; i ++) {
        if(!col[i] && !d[x + i] && !ud[x - i + N]) {
            a[x][i] = 'Q';
            col[i] = d[x + i] = ud[x - i + N] = true;
            dfs(x + 1);
            //回溯(恢复现场)
            col[i] = d[x + i] = ud[x - i + N] = false;
            a[x][i] = '.';
        }
    }
}
int main() {
    cin >> n;
    for(int i = 0; i < n; i ++)
        for(int j = 0; j < n; j ++) 
            a[i][j] = '.';
    
    dfs(0);
    return 0;
}

题目链接

原文地址:https://www.cnblogs.com/woyaoAC/p/14059464.html