POJ1833 排列 全排列模板题 C++ STL 全排列函数详解

全排列概念

从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。如果这组数有n个,那么全排列数为n!个。比如a,b,c的全排列一共有3!= 6 种 分别是{a, b, c}、{a, c, b}、{b, a, c}、{b, c, a}、{c, a, b}、{c, b, a}。

全排列求上下k个排列组合

这里先说两个概念:“下一个排列组合”和“上一个排列组合”,对序列 {a, b, c},每一个元素都比后面的小,按照字典序列,固定a之后,a比bc都小,c比b大,它的下一个序列即为{a, c, b},而{a, c, b}的上一个序列即为{a, b, c},同理可以推出所有的六个序列为:{a, b, c}、{a, c, b}、{b, a, c}、{b, c, a}、{c, a, b}、{c, b, a},其中{a, b, c}没有上一个元素,{c, b, a}没有下一个元素。

  1. 全排列函数:next_permutation:求下k个排列组合 

  2. 函数模板:next_permutation(arr, arr+size)

  3. 函数功能: 返回值为bool类型,当当前序列不存在下一个排列时,函数返回false,否则返回true,排列好的数在数组中存储

  4. 注意:在使用前需要对欲排列数组按升序排序,否则只能找出该序列之后的全排列数。比如,如果数组num初始化为2,3,1,那么输出就变为了:{2 3 1} {3 1 2} {3 2 1}


1. `prev_permutation`:求上k个排列组合

2. 函数模板:`prev_permutation(arr, arr+size)`

3. 函数功能: 同上

4. 注意:在使用前需要对欲排列数组按==降序排序==,否则只能找出该序列之后的全排列数。


##题意
对于每组输入数据,输出一行,n个数,中间用空格隔开,表示输入排列的下k个排列。

##思路
==全排列模板题==,但是因为是直接输出当前排列的下k个排列,而不是全部情况,所以需要注意的就是==本题不需要排序==!!!

##AC代码

==在C++上提交AC,G++TLE==

 ```
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

int a[1050];

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,k;
        scanf("%d %d",&n,&k);
        for(int i=0; i<n; i++)
            scanf("%d",&a[i]);
      //  sort(a,a+n);
      //  for(int i=1;i<=k;i++)
      while(k--)
            next_permutation (a,a+n);
        for(int i=0; i<n-1; i++)
            printf("%d ",a[i]);
        printf("%d\n",a[n-1]);
    }
    return 0;
}
```

##生成1~n的全排列
```
#include <stdio.h>
#include <algorithm>
using namespace std;
int main()
{
    int n;
    while(~scanf("%d",&n)&&n){
        int a[100];
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        sort(a,a+n);
        do
        {
            for(int i=0;i<n;i++)
                printf("%d ",a[i]);
            printf("\n");
        }while(next_permutation(a,a+n));
    }
    return 0;
}
```
原文地址:https://www.cnblogs.com/OFSHK/p/12650093.html