filletoto

导航

排列

      一.next_permutation()函数

STL中求“下一个“全排列的函数是next_permutation()。

它的定义有两种形式:

next_permutation(_BIter, _BIter);
next_permutation(_BIter, _BIter, _Compare);

如果没有下一个排列方式,返回false,否则返回true,并把新的排列放到原来的空间里。

注意,函数的排列范围为[first,last]包括first,不包括last

如果你想得到所有的全排列,那么初始要用sort函数排序,是数组为最小的排列,因为next_permutation()函数是逐渐把序列变大的,而不是一开始就是全部的排列。

 

二.手写排列函数

思路:用数组b记录一个新的全排列,每次递归在剩下的数中选一个,并用vis数组判重

#include <iostream>
using namespace std;
int a[20]={1,2,3,4,5,6,7,8,9,10};
bool vis[20];
int b[20];
void dfs(int s,int t)
{
    if(s==t)//所有数都选过了
    {
                //输出全排列
        for(int i=0;i<t;i++) cout << b[i] << " ";
        cout << endl;
        return ;
    }
    for(int i=0;i<t;i++)
    {
        if(!vis[i])//这个数没有被选过
        {
            vis[i]=true;
            b[s]=a[i];
            dfs(s+1,t);
            vis[i]=false;//回溯
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    int n=3;
    dfs(0,n);//生成前n个数的全排列



    return 0;
}            

时间复杂度为O(n!)

 

三.实战

洛谷P1706 

代码:

#include <bits/stdc++.h>
using namespace std;
int a[20];
bool vis[20];
int b[20];    
int n;
void dfs(int s,int t)
{
    if(s==t)
    {
        for(int i=0;i<t;i++) cout << setw(5) << b[i];
        cout << endl;
        return ;
    }
    for(int i=0;i<t;i++)
    {
        if(!vis[i])
        {
            vis[i]=true;
            b[s]=a[i];
            dfs(s+1,t);
            vis[i]=false;
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=0;i<n;i++) a[i]=i+1;
    dfs(0,n);



    return 0;
}

只需略微修改即可AC。

 

完结撒花!!!

posted on 2024-01-01 11:11  filletoto  阅读(9)  评论(0编辑  收藏  举报