• 康托展开


     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 int x[25],ans[25],j;
     6 long long f[25]={1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800,479001600,6227020800,87178291200,1307674368000,20922789888000,355687428096000,6402373705728000,12164510040883200};//0-19的阶乘(factorial)
     7 long long cantor(int n,int *a){
     8     long long total,sum=0;
     9     for(int i=0;i<n;i++){
    10         total=0;//记录比char[a]大的数的个数(未出现的)
    11         for(int j=i+1;j<n;j++)
    12             if(a[i]>a[j])
    13                 total++;
    14         sum+=total*f[n-1-i];//计算a[i]是1-n的全排列中第几个出现的
    15     }
    16     return sum+1;
    17 }
    18 //1-n的全排列,s排在第k小
    19 void ni_cantor(int n,long long k){
    20     long long t;
    21     bool vis[25];//记录1-n是否已经出现过
    22     memset(vis,0,sizeof(vis));
    23     k--;
    24     for(int i=0;i<n;i++){
    25         t=k/f[n-1-i];//不断/n-1-0的阶乘,得到未出现的数中比第i+1位(从左)小的数的个数
    26         for(j=1;j<=n;j++)//s[i]是1-n中未出现的第t+1小的数
    27             if(!vis[j]){
    28                 if(t==0)
    29                     break;
    30                 t--;
    31             }
    32         ans[i]=j;
    33         vis[j]=1;
    34         k%=f[n-1-i];//取mod继续
    35     }
    36 }
    37 int main(){
    38     int n;
    39     long long m;
    40     scanf("%d%lld",&n,&m);
    41     for(int i=0;i<n;i++)
    42         scanf("%d",&x[i]);
    43     printf("%lld
    ",cantor(n,x));
    44     ni_cantor(n,m);
    45     for(int i=0;i<n-1;i++){
    46         printf("%d ",ans[i]);
    47     }
    48     printf("%d",ans[n-1]);
    49     return 0;
    50 }
  • 相关阅读:
    flutter资料
    flutter兼论
    Dart 学习
    flutter简易教程
    全球15个顶级技术类博客
    Grunt压缩HTML和CSS
    用grunt搭建自动化的web前端开发环境-完整教程
    正确代码之-grunt
    grunt写一个px和rem互转的工具
    unslider使用方法1
  • 原文地址:https://www.cnblogs.com/al76/p/8341152.html
Copyright © 2020-2023  润新知