首先可以参考这一篇博文传送门,这篇博文说的很好,大多数康拓展开都是这样写的,但是俞老师的板子是正好反着进行判断一次,不过也是很好的,附上俞老师的注释与板子
任务:对一个N的全排列,返回一个整数代表它在所有排列中的排名,同样对于一个排名返回原排列,排名从0到N!-1
说明:把排列看成一个多进制数,第i位的进制是(N-i)!。设a[i]=x,前i-1个有k个比x小,那么这一位应该用(i-1-k)*(N-i)!来作为权值,最后加上所有位的权值即可。
用数求排列的时候,从高位到低位一位一位确定,用这一位的权值除以这一位对应的阶乘,若为k,那么从还没用过的数中找出第k+1小的即可。
附上代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=10;
int n,factorial[maxn];
void fac()
{
factorial[0]=1;
factorial[1]=1;
for(int i=2;i<=n;i++){
factorial[i]=factorial[i-1]*i;
}
}
void intToArray(int x,int a[maxn])
{
bool used[maxn];
int i,j,temp;
for(i=1;i<=n;i++){
used[i]=false;
}
for(i=1;i<=n;i++){
temp=x/factorial[n-i];
for(j=1;j<=n;j++){
if(!used[j]){
if(temp==0){
break;
}
--temp;
}
}
a[i]=j;
used[j]=true;
x%=factorial[n-i];
}
}
int arrayToInt(int a[maxn])
{
int i,j,ans=0,temp;
for(int i=1;i<=n;i++){
temp=a[i]-1;
for(int j=1;j<i;j++){
if(a[j]<a[i]){
temp--;
}
}
ans+=factorial[n-i]*temp;
}
return ans;
}
int main()
{
scanf("%d",&n);
fac();
int x,a[maxn];
return 0;
}