洛谷题单指南-暴力枚举-P1706 全排列问题

原题链接:https://www.luogu.com.cn/problem/P1706

题意解读:n个数全排列问题,本质上,给定n个空位,枚举每个能填入空位的数,依次填入,每个数只能填一次。

解题思路:

如何填入n个数呢,可以借助于递归,流程如下:

dfs(填入第k个数)
{
    如果已经填满n个数
        输出结果
        返回
    枚举从1到n的数
        如果当前数没有填过
            填入第k个数
            记录已填入的数已被使用
            dfs(填入第k+1个数)
            释放已填入的数以便回溯
}

下面图示给出递归填数的过程:

最后,给出对应代码

#include <bits/stdc++.h>
using namespace std;

const int N = 15;

int n;
int t[N]; //用来存储1-n个数的一次排列
bool flag[N];

//每次填第k个数
void dfs(int k)
{
    if(k > n) //如果已填满n个数,输出结果
    {
        for(int i = 1; i <= n; i++)
        {
            cout << setw(5) << t[i];
        }
        cout << endl;
        return;
    }
    for(int i = 1; i <= n; i++)
    {
        if(!flag[i]) //如果i没有填过
        { 
            flag[i] = true; //记录i已填
            t[k] = i; //第k个数填i
            dfs(k + 1); //继续填第k + 1个数
            flag[i] = false; //恢复i已填标记,便于回溯
        }  
    }
}

int main()
{
    cin >> n;

    dfs(1);

    return 0;
}

递归调用的顺序如图中红色箭头所示:

posted @ 2024-01-31 15:49  五月江城  阅读(44)  评论(0编辑  收藏  举报