康拓展开模板

#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;
}

猜你喜欢

转载自www.cnblogs.com/wuliking/p/10804741.html
今日推荐