目录
排列数字
利用一维数组标记
利用二进制标记
n-皇后问题
对于关键操作的理解
排列数字
![[DFS模板题] 全排列以及n-皇后问题_算法](https://file.cfanz.cn/uploads/png/2022/06/15/1/0C9WfdR0N1.png)
输入样例:
3输出样例:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
利用一维数组标记
using namespace std;
const int N = 10;
int n,path[N];
bool b[N];
void dfs(int m)
{
    if(m == n){
        for (int i = 0; i < n; i ++ ) cout << path[i] << ' ';
        cout << endl;
        return ;
    }
    
    for (int i = 1; i <= n; i ++ ){
        if(!b[i]){
            path[m] = i;
            b[i] = true;
            dfs(m+1);
            b[i] = false;
        }
    }
}
int main()
{
    cin >> n;
    dfs(0);
    return 0;
}利用二进制标记
using namespace std;
const int N = 10;
int n,path[N];
bool b[N];
void dfs(int m, int state)
{
    if(m == n){
        for (int i = 0; i < n; i ++ ) cout << path[i] << ' ';
        cout << endl;
        return ;
    }
    
    for (int i = 0; i < n; i ++ ){
        if (!(state >> i & 1))
        {
            path[m] = i + 1;
            dfs(m + 1, state + (1 << i));
        }
    }
}
int main()
{
    cin >> n;
    dfs(0, 0);
    return 0;
}n-皇后问题
843. n-皇后问题 - AcWing题库高质量的算法题库https://www.acwing.com/problem/content/845/
using namespace std;
const int N = 20;
int n;
char path[N][N];
bool col[N],dg[N],udg[N];//分别表示同一列,同一正对角线,同一反对角线的占用情况
void dfs(int m)
{
    if(m == n){
        for (int i = 0; i < n; i ++ ) puts(path[i]);
        cout << endl;
        return ;
    }
    
    for (int i = 0; i < n; i ++ ){
        if(!col[i] && !dg[m+i] && !udg[i-m+n]){//★
            path[m][i] = 'Q';
            col[i] = dg[m+i] = udg[i-m+n] = true;
            dfs(m+1);
            col[i] = dg[m+i] = udg[i-m+n] = false;
            path[m][i] = '.';
        }
    }
}
int main()
{
    cin >> n;
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < n; j ++ )
            path[i][j] = '.';
    dfs(0);
    return 0;
}对于关键操作的理解
这里妙就妙在对于状态的判定上
!col[i] && !dg[m+i] && !udg[i-m+n]col 数组是表示该列是否被占用,比较好理解
dg 数组表示该位置(横坐标为m,纵坐标为i)所在的正向对角线(即右上到左下)是否被占用,我们可以从中看出规律,同一正对角线的横纵坐标加和相等
而udg 数组表示该位置所在的反对角线(即左上到右下)是否被占用,从中看出规律,同一反对角线的横纵坐标差值相等,而我们定义的udg 数组下标是从0开始的,为了使之合理,我们给他加个足以满足"差值+x>=0"的x, 通俗来说就是使物以类聚,并且聚得方便操作,所以上面的i-m+n也可以写作m-i+n或者m-i+15, i-m+16之类的
                









