题目描述
如果一个整数序列 𝑎1,𝑎2,…,𝑎𝑛a1,a2,…,an 的每个数字都在 11 到 𝑛n 之间,且没有两个数字相等,则称这个序列为全排列。例如1,3,21,3,2 以及 4,3,2,14,3,2,1 都是全排列。
我们将所有的全排列排序,定义全排列 𝑎1,𝑎2,…,𝑎𝑛a1,a2,…,an 与 𝑏1,𝑏2,…,𝑏𝑚b1,b2,…,bm 的排序先后关系如下:
- 如果 𝑛<𝑚n<m,则 𝑎a 序列更靠前
- 如果 𝑛>𝑚n>m,则 𝑏b 序列更靠前
- 如果 𝑛=𝑚n=m,则以字典序规则比较 𝑎a 序列与 𝑏b 序列,字典序更小的序列更靠前。
根据上述定义,可以得到
- 第 11 个全排列是 11
- 第 22 个全排列是 1 21 2
- 第 33 个全排列是 2 12 1
- 第 44 个全排列是 1 2 31 2 3
给定 𝑘k,请输出第 𝑘k 个全排列。
输入格式
- 单个整数:表示 𝑘k
输出格式
- 单独一行:表示第 𝑘k 个全排列
数据范围
- 30%30% 的数据 1≤𝑘≤10001≤k≤1000
- 60%60% 的数据 1≤𝑘≤1,000,0001≤k≤1,000,000
- 100%100% 的数据 1≤𝑘≤10151≤k≤1015
样例数据
输入:
5
输出:
1 3 2
详见代码:
#include <bits/stdc++.h>
using namespace std;
long long k;
long long jc[105];
bool b[55];
int w;
void myprint(long long s,int step)
{
if (step==0) return;
long long x=(s-1)/jc[step-1]+1;
for (int i=1;i<=w;i++)
{
if (b[i]==0)
{
x--;
if (x==0)
{
printf("%d ",i);
b[i]=1;
break;
}
}
}
s%=jc[step-1];
if (s==0) s=jc[step-1];
myprint(s,step-1);
}
int main()
{
cin>>k;
jc[0]=1;
long long sum=0;
for (int i=1;sum<=k;i++)
{
jc[i]=jc[i-1]*i;
sum+=jc[i];
w=i;
}
for (int i=1;i<w;i++)
{
k-=jc[i];
}
myprint(k,w);
return 0;
}