Ignatius and the Princess II
- 题目大意
给你n个数的全排列,现在让你求这n个全排列的第m小个。
- 题解
第一感觉是一个逆康托展开的问题…直接用康托展开的定义反着求就行了(写的有点麻烦)。
- 代码
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
using namespace std;
int cos[9]={1,1,2,6,24,120,720,5040,40320};
int m,n,ans[8],h,c[8],f[8];
int main()
{
while (scanf("%d%d",&n,&m)!=EOF)
{
memset(ans,0,sizeof(ans));
memset(f,0,sizeof(f));
if (n<=8) for (int i=0;i<n;i++) c[i]=i+1;
else for (int i=n-7,h=0;i<=n;i++,h++) c[h]=i;
h=0;
for(int i=1;i<=min(n,8);i++)
{
int j=0,q=0,k=0,p;
if (n>8) p=8-i;
else p=n-i;
while (j*cos[p]<m) j++;
j--;
m=m-j*cos[p];
while (q!=j+1)
{
if (!f[k]) q++;
k++;
}
ans[h++]=c[k-1];
f[k-1]=1;
}
for (int i=1;i<=n-8;i++) printf("%d ",i);
for (int i=0;i<h-1;i++) printf("%d ",ans[i]);
printf("%d\n",ans[h-1]);
}
return 0;
}