加载中...

信息奥赛题解|排列


信息奥赛题解|排列


🚀 题目浏览

【题目描述】

大家知道,给出正整数 $n$,则 $1$ 到 $n$ 这 $n$ 个数可以构成 $n!$ 种排列,把这些排列按照从小到大的顺序(字典顺序)列出,如 $n=3$ 时,列出 1 2 3,1 3 2,2 1 3,2 3 1,3 1 2,3 2 1 六个排列。

给出某个排列,求出这个排列的下 $k$ 个排列,如果遇到最后一个排列,则下 $1$ 排列为第 $1$个排列,即排列 1 2 3…n。

比如:$n = 3,k=2$ 给出排列 2 3 1,则它的下 $1$ 个排列为 3 1 2,下 $2$ 个排列为 3 2 1,因此答案为 3 2 1。

【输入】

第一行是一个正整数 $m$,表示测试数据的个数,下面是m组测试数据,每组测试数据第一行是 $2$ 个正整数 $n(1 \le n \lt 1024 ) $和 $k(1 \le k \le 64)$,第二行有 $n$ 个正整数,是 1,2 … n的一个排列。

【输出】

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

【输入样例】

3
3 1
2 3 1
3 1
3 2 1
10 2	
1 2 3 4 5 6 7 8 9 10

【输出样例】

3 1 2
1 2 3
1 2 3 4 5 6 7 9 8 10

【题目来源】

https://vjudge.net/problem/POJ-1833


☘️ 题解分析

结合 STL 中的 next_permutation() 使用,效果巨佳。

PS:POJ 上不能使用万能头,想要使用 next_permutation(),需要添加 <algorithm> 头文件。


🧑🏻‍💻 C++ 代码

#include <iostream>
#include <algorithm>

using namespace std;
typedef long long LL;
const int N = 1100;
int n, a[N], T, k;

int main() {
    ios::sync_with_stdio(false);  //cin读入优化
    cin.tie(0);

    cin >> T;
    while (T--) {
        // 读入数据
        cin >> n >> k;
        for (int i = 1; i <= n; i++) cin >> a[i];

        // 利用next_permutation()函数,自动求下一个排列
        // next_permutation()会自动从最后一个排列回到第一个
        while (k--) next_permutation(a + 1, a + n + 1);

        // 输出结果
        for (int i = 1; i <= n; i++) cout << a[i] << " ";
        cout << endl;
    }

    return 0;
}

文章作者: Rickyの水果摊
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Rickyの水果摊 !
  目录