康托展开式的逆过程,也可以用库函数写
//康托展开式(不懂百度百科,写的很详细)这题是一个逆过程
//8位的数一共有40000多种排序远大于题目要求的10000;
//所以八位以前的数不变。
#include<iostream>
using namespace std;
__int64 fac[]={1,1,2,6,24,120,720,5040,40320,362880,362880};
int ch[1000];
int n, num;
void ss()
{
int i, j, k, mode, nn=n;
memset(ch, 0, sizeof(ch));
if(n > 8)//超过8位的前面1~n-8不变,后面排序
{
for( i=0; i < n-8; i++ )
ch[i] = i+1;
nn = 8;
}
num--;
for( i=nn-1; i > 0; i-- )
{
mode = num % fac[i];
num /= fac[i];
int temp=0;
for( j=1; j <= n; j++ )//遍历在这个位子以前哪些数是用过的
{
for( k=0; k < n-i-1; k++ )
{
if(ch[k] == j)
break;
}
if(k == n-i-1)
temp++;
if(temp == num+1)
{
ch[n-i-1]=j;
break;
}
}
num = mode;
}
for(i=1; i <= n; i++ )//寻找最后一位数
{
for(j=0; j < n; j++ )
{
if(ch[j] == i)
break;
}
if(j == n)
{
ch[n-1] = i;
break;
}
}
}
int main()
{
while(scanf("%d%d", &n, &num) != EOF )
{
ss();
bool p = false;
for(int i=0; i < n; i++ )
{
if(p)
printf(" ");
p = true;
printf("%d", ch[i]);
}
printf("\n");
}
return 0;
}
库函数next_permutstion
//库函数next_permutaion(a, a+n)
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int n, m, i, j, a[1005];
while(scanf("%d%d", &n, &m) != EOF)
{
for( i=0; i < n; i++ )
a[i] = i+1;
while(--m) { next_permutation(a, a+n); }
bool p = false;
for( i=0; i < n; i++ )
{
if(p)
printf(" ");
p = true;
printf("%d", a[i]);
}
printf("\n");
}
return 0;
}