【康托展开】

展开

1.  例子  求 {2,5,4,3,1} 在集合{1,2,3,4,5}全排列中所处的位置

    (1) 比2小得数有 1个 所以为 1*4!个       

    (2) 比5小得并且在前面没有出现的数(比如 2) 有 3个 所以为 3*3!个

    (3) 比4小得并且在前面没有出现的数(比如 2) 有 2个 所以为 2*2!个

    (4) 比3小得并且在前面没有出现的数(比如 2) 有 1个 所以为 1*1! 个

      所以{2,5,4,3,1} 在集合{1,2,3,4,5}全排列中所处的位置为3*3!+2*2!+1*1!+1*0!=24   

    void JSContor()
    {
        int temp=0,p=1;
        for(int i=8;i>=0;i--)
        {
            int tot=0;
            for(int j=0;j<i;j++)
                if(A[j]<A[i]) tot++;
            temp+=(A[i]-tot-1)*p;
            p=p*(9-i);
        }
        Contor=temp+1;
    }

如果N很大 可以用线段树做到NlogN



逆展开

      例 {1,2,3,4,5}的全排列,并且已经从小到大排序完毕

  (1)找出第96个数

  首先用96-1得到95

  用95去除4! 得到3余23

  用23去除3! 得到3余5

  用5去除2!得到2余1

  用1去除1!得到1余0有3个数比它小的数是4

  所以第一位是4

  有3个数比它小的数是4但4已经在之前出现过了所以是5(因为4在之前出现过了所以实际比5小的数是3个)

  有2个数比它小的数是3

  有1个数比它小的数是2

  最后一个数只能是1

  所以这个数是45321

  (2)找出第16个数

  首先用16-1得到15

  用15去除4!得到0余15

  用15去除3!得到2余3

  用3去除2!得到1余1

  用1去除1!得到1余0

  有0个数比它小的数是1

  有2个数比它小的数是3 但由于1已经在之前出现过了所以是4(因为1在之前出现过了所以实际比4小的数是2)

  有1个数比它小的数是2 但由于1已经在之前出现过了所以是3(因为1在之前出现过了所以实际比3小的数是1)

  有1个数比它小得数是2 但由于1,3,4已经在之前出现过了所以是5(因为1,3,4在之前出现过了所以实际比5小的数是1)

  最后一个数只能是2

  所以这个数是14352



posted on 2015-04-13 11:12  DDUPzy  阅读(135)  评论(0编辑  收藏  举报

导航