首页 > 其他 > 详细

康拓展开模板

时间:2019-05-03 13:14:17      阅读:148      评论:0      收藏:0      [点我收藏+]

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int f[]={1,1,2,6,24,120,720,5040,40320,362880,3628800}; ///算出1-9的阶乘,0的阶乘用1代替
int cantor(int *a,int n) {
int ans=0,rk;
for(int i=1;i<n;i++) {
rk=0;
for(int j=i+1;j<=n;j++) ///计算位于i后面的数小于a[i]的个数,rk即为i的排名
if(a[j]<a[i])
rk++;
ans+=rk*f[n-i]; ///据公式X = A[0] * (n-1)! + A[1] * (n-2)! + … + A[n-1] * 0!
///A[i] = rk
}
return ans+1; ///ans+1,即为原序列在全排列中的次序
}
void decantor(int x,int n,int *a) {
bool vis[10];
memset(vis,false,sizeof(vis));
for(int i=0;i<n;i++) {
int rk=x/f[n-i-1];
for(int j=0;j<=rk;j++) ///与上述同理,已访问过的数不在序列中,所以要将rk++
if(vis[j]) rk++;
a[i]=rk+1; ///求得的rk是比A[i]小的数的个数,所以A[i]=rk+1
vis[rk]=true;
x%=f[n-i-1];
}
}
int main()
{
int t,n,oper,a[11],v;
cin>>t;
while(t--) {
cin>>oper;
if(!oper) {
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
cout<<cantor(a,n)<<endl;
}
else {
cin>>n>>v;
decantor(v-1,n,a);
for(int i=0;i<n;i++)
cout<<a[i]<<‘ ‘;
cout<<endl;
}
}
return 0;
}

康拓展开模板

原文:https://www.cnblogs.com/wuliking/p/10804741.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!