• 首先可以考虑自己写dfs函数对全排列问题进行求解。

参考代码如下:

#include<iostream>
using namespace std;
int a[10010],b[10010];
long long int total=0;
int n;
void dfs(int k)
{
    if(k>n)
    {
       total++;//记录方案个数
       for(int i=1;i<=n;i++)
       cout<<b[i]<<" ";
       cout<<endl;
     return;
    }
    for(int i=1;i<=n;i++)//尝试在b[k]中填写各种整数的i
    {
        int ok=1;
        for(int j=1;j<k;j++)
        if(b[j]==i)
        {
           ok=0;//如果i已经在b[1]~b[k-1]出现过,则不能再选
           //break;
        }
        if(ok)
        {
             b[k]=i;
             dfs(k+1);//进行下一个元素的全排列
        }
    }

}
int main()
{
	ios::sync_with_stdio(false);
	cin >> n;//输入元素个数
	for (int i = 1;i <= n;i++)
		cin >> a[i];
    for(int i=1;i<=n;i++)
         dfs(i);
    cout<<"所有排列方案数为:"<<total<<endl;
    return 0;
}

练习题目:

1.Luogu:火星人

  • C++的STL库中有next_permutation()函数可以对数字进行全排列,下面对这个函数的用法进行详细的介绍。具体请参考下面这篇博客:

kuangbin之next_permutation函数

- 康托展开(全排列和序号之间的映射)

康托展开解决的两个问题:

正康托展开:给出一个全排列的序列,求该序列是第几个全排列的序列。

如初始序列1234,那么3214是第15个全排列的序列。

逆康托展开:给出数字k,求全排列序列中的第k个序列是什么。

如初始序列1234,第15个全排列的序列为3214。

康托展开是为了解决全排列和序号之间的映射问题,对于全排列,可以通过next_permutation(a,a+n)(或者pre_permutation(a,a+n))去求解,当然也可以自己写一个递归回溯函数求解。
具体的讲解可以了解维基百科中对此的讲解。

传送门