日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

康托展开式---我排第几+逆康托展开

發(fā)布時(shí)間:2025/3/18 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 康托展开式---我排第几+逆康托展开 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

之前一直不想看這個(gè)康托展開定理因?yàn)檎娴暮懿焕斫?#xff0c;但是現(xiàn)在還是勇敢的面對(duì)了~

?{1,2,3,4,...,n}表示1,2,3,...,n的排列如 {1,2,3} 按從小到大排列一共6個(gè)。123 132 213 231 312 321 。 代表的數(shù)字 1 2 3 4 5 6 也就是把10進(jìn)制數(shù)與一個(gè)排列對(duì)應(yīng)起來。 他們間的對(duì)應(yīng)關(guān)系可由康托展開來找到。 如我想知道321是{1,2,3}中第幾個(gè)大的數(shù)可以這樣考慮 : 第一位是3,當(dāng)?shù)谝晃坏臄?shù)小于3時(shí),那排列數(shù)小于321 如 123、 213 ,小于3的數(shù)有1、2 。所以有2*2!個(gè)。再看小于第二位2的:小于2的數(shù)只有一個(gè)就是1 ,所以有1*1!=1 所以小于321的{1,2,3}排列數(shù)有2*2!+1*1!=5個(gè)。所以321是第6個(gè)大的數(shù)。 2*2!+1*1!+0*0!就是康托展開。 再舉個(gè)例子:1324是{1,2,3,4}排列數(shù)中第幾個(gè)大的數(shù):第一位是1小于1的數(shù)沒有,是0個(gè) 0*3! 第二位是3小于3的數(shù)有1和2,但1已經(jīng)在第一位了,所以只有一個(gè)數(shù)2 1*2! 。第三位是2小于2的數(shù)是1,但1在第一位,所以有0個(gè)數(shù) 0*1! ,所以比1324小的排列有0*3!+1*2!+0*1!=2個(gè),1324是第三個(gè)大數(shù)。 把一個(gè)整數(shù)X展開成如下形式: ? ?X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[2]*1!+a[1]*0! ? ?其中,a為整數(shù),并且0<=a[i]<i(1<=i<=n) #include<stdio.h> #include<string.h>int a[14];char s[15];void factorial(){int i;a[0]=1;a[1]=1;for(i=2;i<14;i++)a[i]=i*a[i-1];}int cator(){factorial();// puts("++");int i,j,ans=0,cout ;for(i=0;i<12;i++){ cout=0;for(j=i+1;j<12;j++){if(s[i]>s[j])cout++;}ans+=cout*a[11-i];}return ans+1;}int main(){int ncase;scanf("%d",&ncase);while(ncase--){scanf("%s",s);printf("%d\n",cator());}return 0;}

二、康托展開的逆運(yùn)算

點(diǎn)擊打開鏈接

例1 {1,2,3,4,5}的全排列,并且已經(jīng)從小到大排序完畢
(1)找出第96個(gè)數(shù)
首先用96-1得到95
用95去除4! 得到3余23
用23去除3! 得到3余5
用5去除2!得到2余1
用1去除1!得到1余0

有3個(gè)數(shù)比它小的數(shù)是4
所以第一位是4
有3個(gè)數(shù)比它小的數(shù)是4但4已經(jīng)在之前出現(xiàn)過了所以是5(因?yàn)?在之前出現(xiàn)過了所以實(shí)際比5小的數(shù)是3個(gè))
有2個(gè)數(shù)比它小的數(shù)是3
有1個(gè)數(shù)比它小的數(shù)是2

最后一個(gè)數(shù)只能是1
所以這個(gè)數(shù)是45321

(2)找出第16個(gè)數(shù)
首先用16-1得到15
用15去除4!得到0余15
用15去除3!得到2余3
用3去除2!得到1余1
用1去除1!得到1余0

有0個(gè)數(shù)比它小的數(shù)是1
有2個(gè)數(shù)比它小的數(shù)是3 但由于1已經(jīng)在之前出現(xiàn)過了所以是4(因?yàn)?在之前出現(xiàn)過了所以實(shí)際比4小的數(shù)是2)
有1個(gè)數(shù)比它小的數(shù)是2 但由于1已經(jīng)在之前出現(xiàn)過了所以是3(因?yàn)?在之前出現(xiàn)過了所以實(shí)際比3小的數(shù)是1)
有1個(gè)數(shù)比它小得數(shù)是2 但由于1,3,4已經(jīng)在之前出現(xiàn)過了所以是5(因?yàn)?,3,4在之前出現(xiàn)過了所以實(shí)際比5小的數(shù)是1)

最后一個(gè)數(shù)只能是2
所以這個(gè)數(shù)是14352

#include<stdio.h> #include<string.h> int a[12],flag[12],finish[12]; void find() {a[11]=1;int j=1;for(int i=10;i>=0;i--){a[i]=a[i+1]*j;j++;} //計(jì)算階乘記得階乘是從小到大的。從左到右的 } int main() {int n,sum,j;find();scanf("%d",&n);while(n--){scanf("%d",&sum);sum-=1; //yao除去它本身memset(flag,0,sizeof(flag));for(int i=0;i<12;i++){int cout=sum/a[i];for( j=0;j<12;j++){if(!flag[j]){if(cout==0)break; //這樣可以標(biāo)記到前面是否算過的,從沒算過的開始,。cout--;}}flag[j]=1;finish[i]=j;sum=sum%a[i];}for(int i=0;i<12;i++)printf("%c",'a'+finish[i]);printf("\n");}return 0; }


總結(jié)

以上是生活随笔為你收集整理的康托展开式---我排第几+逆康托展开的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。