上海市计算机学会竞赛平台2023年7月月赛丙组排列排序

题目描述

如果一个整数序列 𝑎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;
}

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值