1/20集训一 STL I.(next_permutation 寻找第N小序列子串) Ignatius and the Princess II

1/20集训一 STL

I.(next_permutation (algorithm) 寻找第N小序列子串) Ignatius and the Princess II

Now our hero finds the door to the BEelzebub feng5166. He opens the door and finds feng5166 is about to kill our pretty Princess. But now the BEelzebub has to beat our hero first. feng5166 says, “I have three question for you, if you can work them out, I will release the Princess, or you will be my dinner, too.” Ignatius says confidently, “OK, at last, I will save the Princess.”
“Now I will show you the first problem.” feng5166 says, “Given a sequence of number 1 to N, we define that 1,2,3…N-1,N is the smallest sequence among all the sequence which can be composed with number 1 to N(each number can be and should be use only once in this problem). So it’s easy to see the second smallest sequence is 1,2,3…N,N-1. Now I will give you two numbers, N and M. You should tell me the Mth smallest sequence which is composed with number 1 to N. It’s easy, isn’t is? Hahahahaha……”
Can you help Ignatius to solve this problem?
Input
The input contains several test cases. Each test case consists of two numbers, N and M(1<=N<=1000, 1<=M<=10000). You may assume that there is always a sequence satisfied the BEelzebub’s demand. The input is terminated by the end of file.
Output
For each test case, you only have to output the sequence satisfied the BEelzebub’s demand. When output a sequence, you should print a space between two numbers, but do not output any spaces after the last number.
Sample Input
6 4
11 8
Sample Output
1 2 3 5 6 4
1 2 3 4 5 6 7 9 8 11 10

题意:
给出 n, m, 询问 n 个数的全排列的第 m 个排列是什么。

思路:
本题可以用康托展开求解。
当然可以利用 STL 中的 next_ permutation, 第 m 个排列就是对最小的排列求 m-1 次的 next_permutationde。
首先要理解什么排列的大小怎么区分, 例如有 a, b, c 三个数, 那么 abc 就是最小的排列, acb 是他下一个排列, cba 是最大的排列, 也就是根据字典序排序的。

#include <iostream>
#include <stdio.h>
#include <algorithm>
#define MAXN 1005
using namespace std;

int main()
{
    int n, m;
    while(scanf("%d%d", &n, &m) != EOF)
    {
        int a[MAXN];
        for(int i = 0; i < n; i++)
        {
            a[i] = i + 1;
        }
        for(int i = 0; i < m - 1; i++)
            next_permutation(a, a + n);
        for(int i = 0; i < n - 1; i++)
            cout<<a[i]<<' ';
        cout<<a[n - 1]<<endl;
    }
    return 0;
}

提示:
要记得包含头文件#include algorithm
在STL中,除了next _ permutation外,还有一个函数prev_permutation,两者都是用来计算排列组合的函数。前者是求出下一个排列组合,而后者是求出上一个排列组合。所谓“下一个”和“上一个”,书中举了一个简单的例子:对序列 {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}没有下一个元素。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值