大家知道,给出正整数 nn,则 11 到 nn 这 nn 个数可以构成 n!n! 种排列,把这些排列按照从小到大的顺序(字典顺序)列出,如 n=3n=3 时,列出 \text{1 2 3,1 3 2,2 1 3,2 3 1,3 1 2,3 2 1}1 2 3,1 3 2,2 1 3,2 3 1,3 1 2,3 2 1 六个排列。
蒜头君给出某个排列,求出这个排列的下 kk 个排列,如果遇到最后一个排列,则下 11 排列为第 11 个排列,即排列 1 2 3…n123…n。
比如:n = 3n=3,k=2k=2 给出排列 \text{2 3 1}2 3 1,则它的下 11 个排列为 \text{3 1 2}3 1 2,下 22 个排列为 \text{3 2 1}3 2 1,因此答案为 \text{3 2 1}3 2 1。
输入格式
第一行是一个正整数 mm,表示测试数据的个数,下面是 mm 组测试数据,每组测试数据第一行是 22 个正整数 nn( 1 \le n < 10241≤n<1024) 和 k(1 \le k \le 64)k(1≤k≤64),第二行有 nn 个正整数,是 1, 2 … n1,2…n 的一个排列。
输出格式
对于每组输入数据,输出一行,nn 个数,中间用空格隔开,表示输入排列的下 kk 个排列。
Sample 1
Inputcopy | Outputcopy |
---|---|
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 |
这一题可以说是完全为STL库量身定做的题目,如果不知道这个函数估计也就只能用dfs来做了。
首先介绍一下这个函数,这个函数的功能是对指定的数组,字符数组等进行按字典序列全排序,可以升序当然也可以降序,升序函数是next_permutation(a,a+n)括号里的参数意思和sort函数一样,使用一次会让数组里的数顺序变成下一种典序,就和这道题一样,但能变一次,所以需要变几次借助for循环即可,当然也有升序,就是prev_permutation(a,a+n),详细代码参考如下:
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int n;
cin>>n;
int a[1060];
while(n--)
{
int x,y;
cin>>x>>y;
for(int i=0;i<x;i++)
{
cin>>a[i];
}
while(y--)
next_permutation(a,a+x);
for(int i=0;i<x;i++)
cout<<a[i]<<' ';
cout<<endl;
}
return 0;
}
全排列问题
按照字典序输出自然数 11 到 nn 所有不重复的排列,即 nn 的全排列,要求所产生的任一数字序列中不允许出现重复的数字。
Input
一个整数 nn。
Output
由 1 \sim n1∼n 组成的所有不重复的数字序列,每行一个序列。
每个数字保留 55 个场宽。
Sample 1
Inputcopy | Outputcopy |
---|---|
3 | 1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1 |
Hint
1 \leq n \leq 91≤n≤9。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
int a[n];
for(int i=0;i<n;i++)
a[i]=i+1;
int sum=1;
int b=n;
while(b!=1)
{
sum=sum*b;
b--;
}
for(int i=0;i<sum;i++)
{
for(int j=0;j<n;j++)
cout<<" "<<a[j];
cout<<endl;
next_permutation(a,a+n);
}
return 0;
}
下面是dfs版本
#include<bits/stdc++.h>
using namespace std;
int a[100];
bool vis[100];
int n;
void dfs(int step)
{
if(step==n)
{
for(int i=0;i<n;i++)
cout<<" "<<a[i];
cout<<'\n';
return ;
}
for(int i=1;i<=n;i++)
{
if(!vis[i])
a[step]=i;
else
continue;
vis[i]=1;
dfs(step+1);
vis[i]=0;
}
}
int main()
{
cin>>n;
dfs(0);
return 0;
}