• 康托展开和逆康托展开


    康托展开是一个全排列到一个自然数的双射,常用于构建hash表时的空间压缩。设有n个数(1,2,3,4,…,n),可以有组成不同(n!种)的排列组合,康托展开表示的就是是当前排列组合在n个不同元素的全排列中的名次。

    逆康托展开给一个数字求出第几个排列组合。

    给出n和操作数k,要求资瓷: 
    P x求n的第x个排列 
    Q 一个n的排列 求这是第几个排列 
    n<=20

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #define N 25
    #define LL long long
    using namespace std;
    
    int n,k,a[N],vis[N];
    LL jc[N];
    
    void solve1()
    {
        LL x;
        scanf("%lld",&x);x--;
        memset(vis,0,sizeof(vis));
        for (int i=n-1;i>=0;i--)
        {
            int num=x/jc[i],now=0;x%=jc[i];
            for (int j=1;j<=n;j++)
                if (!vis[j])
                {
                    if (now==num)
                    {
                        vis[j]=1;printf("%d",j);if (i) cout<<' ';break;
                    }
                    else now++;
                }
        }
        cout<<endl;
    }
    
    void solve2()
    {
        for (int i=n;i;i--) scanf("%d",&a[i]);
        LL ans=0;
        for (int i=n-1;i>=0;i--)
        {
            LL s=0;
            for (int j=1;j<=i;j++) if (a[j]<a[i+1]) s++;
            ans+=s*jc[i];
        }
        printf("%lld
    ",ans+1);
    }
    
    int main()
    {
        scanf("%d%d",&n,&k);
        jc[0]=1;
        for (int i=1;i<n;i++) jc[i]=(LL)jc[i-1]*i;
        for (int i=1;i<=k;i++)
        {
            char ch[2];
            scanf("%s",ch);
            if (ch[0]=='P') solve1();
            else solve2();
        }
        return 0;
    }
  • 相关阅读:
    Linux入门
    Linux和VMware
    vue中select的使用以及select设置默认选中
    Django ModelFrom组件
    Django登录(含随机生成图片验证码)注册实例
    Django组件---Django请求生命周期和中间件
    Python3之使用Crypto
    ORM大结局
    ORM多表查询下
    Pycharn破解补丁激活
  • 原文地址:https://www.cnblogs.com/shuaihui520/p/8988144.html
Copyright © 2020-2023  润新知