康托展开及其逆运算

一、康托展开

(1)找出45231在这个排列中的顺序

比4小的数有3个
比5小的数有4个但4已经在之前出现过了所以是3个
比2小的数有1个
比3小的数有两个但2已经在之前出现过了所以是1个
比1小的数有0个

二、康托展开的逆运算

(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

 

#include #include #include #include using namespace std; int main() { int t,i,j,scur; long long sum,st; char str[15]; //freopen("E://input.txt","r",stdin); scanf("%d",&t); while(t--) { sum=0; scanf("%s",&str); for (i=0;i<12;i++) { st=1; scur=str[i]-'a'; for (j=0;j

 

#include #include #include #include using namespace std; int ji[12]={1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800}; int main() { int t,i,j,pm[13]={1,2,3,4,5,6,7,8,9,10,11,12},scur; int sum,st; char str[15]; // freopen("E://input.txt","r",stdin); scanf("%d",&t); while(t--) { memset(str,0,sizeof(str)); scanf("%ld",&sum); sum--; for (i=1;i<13;i++) { st=ji[12-i]; scur=sum/st; sum-=scur*st; str[i-1]='a'+pm[scur]-1; for (j=scur;j<=12;j++) pm[j]=pm[j+1]; } printf("%s/n",str); for (i=0;i<12;i++) { pm[i]=i+1; } } return 0; }

你可能感兴趣的:(康托展开及其逆运算)