洛谷 P1706 全排列问题

 

以下有两种解法,一种是深度优先搜索,一种是利用c++中的库函数next_permutation()函数

人比较懒,所以下面就讲解一下稍微简单易懂的第二种解法

 

简单描述一下next_permutation()函数的用法(个人理解)

bool  next_permutation(iterator start,iterator end)

函数返回一个bool类型的值,参数是迭代器起始到终止

通常是以数组为函数的操作对象,函数会改变数组中元素的位置,自动进行排列,如果当前数组中的下一个排列存在则返回true 否则返回false

举个例子:  对1,2,3  进行全排列(结果按字典升序)

结果为:

1 2 3

1 3 2

2 1 3

2 3 1

3 1 2

3 2 1

其中1 2 3为第一组排序,3 2 1为最后一组排序,当数组中的数列为3 2 1时下一步操作时next_permutation()函数将会返回false,因为3 2 1已经是最后一组排列了,在它后面已经没有其他的排列了。

所以,通常情况下用next_permutation()函数求全排列时,数组最初值一定要是全排列中最小的排列(在上面的例子中也就是1 2 3)

如果初始时数组中顺序不是最小的那组排列,则用next_permutation()函数求排列时,只能得到初始排列后面比初始排列字典序大的排列

使用格式

do{
for(int i=1;i<=n;i++)
  cout<<s[i];
cout<<endl;
}while(next_permutation(s,s+n));

 

洛谷 P1706 全排列问题

有了以上知识,对于洛谷这道全排列的题解起来就很简单了

以下代码包括 深度优先搜索版本 和 next_permutation()函数版本

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

    int res[10];
    int vis[10];
    int n;
    void dfs(int step)
    {
        if (step == n + 1)
        {
            for (int i = 1; i <= n; i++)
                printf("%5d",res[i]);
            cout << endl;
            return;
        }

        for (int i = 1; i <= n; i++)
        {
            if (vis[i] == 0)
            {
                res[step] = i;
                vis[i] = 1;
                dfs(step + 1);
                vis[i] = 0;
            }
        }
    }
    //深度优先搜索
    void test()
    {
        cin >> n;
        dfs(1);
    }
    
    //next_permutation()全排列函数
    void test01()
    {
        int n;
        cin>>n;
        int s[10]={0,1,2,3,4,5,6,7,8,9};
        do{
            for(int i=1;i<=n;i++)
            printf("%5d",s[i]);
            cout<<endl;
        }while(next_permutation(s+1,s+n+1));
    }
int main()
{
    // test();
    test01();
    return 0;
}

 

posted @ 2022-03-18 21:15  深情的山鸡  阅读(160)  评论(0编辑  收藏  举报