zoukankan      html  css  js  c++  java
  • 康托展开和逆康托展开的实现

    康托展开的应用实例

    {1,2,3,4,...,n}表示1,2,3,...,n的排列如 {1,2,3} 按从小到大排列一共6个。123 132 213 231 312 321 。
    代表的数字 1 2 3 4 5 6 也就是把10进制数与一个排列对应起来。
    他们间的对应关系可由康托展开来找到。
    如我想知道321是{1,2,3}中第几个大的数可以这样考虑 :
    第一位是3,当第一位的数小于3时,那排列数小于321 如 123、 213 ,小于3的数有1、2 。所以有2*2!个。再看小于第二位2的:小于2的数只有一个就是1 ,所以有1*1!=1 所以小于321的{1,2,3}排列数有2*2!+1*1!=5个。所以321是第6个大的数。 2*2!+1*1!+0*0!就是康托展开。
    再举个例子:1324是{1,2,3,4}排列数中第几个大的数:第一位是1小于1的数没有,是0个 0*3! 第二位是3小于3的数有1和2,但1已经在第一位了,所以只有一个数2 1*2! 。第三位是2小于2的数是1,但1在第一位,所以有0个数 0*1! ,所以比1324小的排列有0*3!+1*2!+0*1!=2个,1324是第三个大数。
     
     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<math.h>
     4 #include<algorithm>
     5 #include<string.h>
     6 #include<string>
     7 #include<ctime>
     8 #include<queue>
     9 #include<list>
    10 #include<map>
    11 #include<set>
    12 #define INF 999999999
    13 #define MAXN 10000000
    14 using namespace std;
    15 int fac[] = {1,1,2,6,24,120,720,5040,40320,362880};
    16 
    17 //康托展开:
    18 int cantor(int* a, int k) 
    19 {
    20     int i, j, tmp, num = 0;
    21     for (i = 0; i < k; i++) {
    22         tmp = 0;
    23         for (j = i + 1; j < k; j++)
    24             if (a[j] < a[i])
    25                 tmp++;
    26         num += fac[k - i - 1] * tmp;
    27     }
    28     return num;
    29 }
    30 
    31 //逆康托展开:
    32 int* uncantor(int x, int k) {
    33     int res[100];
    34     int i, j, l, t;
    35     bool h[100]={0};
    36     for (i = 1; i <= k; i++) 
    37     {
    38         t = x / fac[k - i];
    39         x -= t * fac[k - i];
    40         for (j = 1, l = 0; l <= t; j++)
    41             if (!h[j])
    42                 l++;
    43         j--;
    44         h[j] = true;
    45         res[i - 1] = j;
    46     }
    47     return res;
    48 }
    49 
    50 int main()
    51 {
    52     int n,a[1000];
    53     while(~scanf("%d",&n))
    54     {
    55         int i;
    56         for(i=0;i<n;i++)
    57             scanf("%d",&a[i]);
    58         int res=cantor(a,n);
    59         printf("%d\n",res);
    60         int *b=uncantor(res,n);
    61         for(i=0;i<n;i++)
    62             printf("%d ",b[i]);
    63         putchar(10);
    64 
    65     }
    66     return 0;
    67 }
  • 相关阅读:
    mongoDB 小练习
    pymongo 操作
    mongoDB 大文件存储方案, JS 支持展示
    mongoDB 固定集合
    mongoDB 聚合操作
    mongoDB 索引
    mongoDB 其他数据类型
    mongoDB 文档操作_删
    mongoDB 文档操作_改
    【探讨】linux环境,执行重启了php后php.ini依然不生效
  • 原文地址:https://www.cnblogs.com/crazyapple/p/3008691.html
Copyright © 2011-2022 走看看