本题就是求全排列n的第m个序列;这个真心想了半天;
首先,3 2
3是全排列:
123 132
213 231
312 321
即第一位为1-3,每个有2!=2个,第二位为剩余的两个的排序,如果给剩余的标号为0,1,则为01,10;
4 4
1234 1243 1324 1342 1423 1432
2134 2143.。。。
什么规律?
第i位为前i-1位排列后剩下的说的全排列;如,第一位为1,后3位为234的全排列;所以想确定第一位为1-4的哪一个,只需
m/3!即可,求下一位时m=m%3!;
这就好弄了,一位一位的求出来就行了。
但n==1000啊!!求n!???????突然发现m却只有10000啊;这说明只许求前10000个的n排列,判断知道,8!>10000;
即只有后8位在变,8位之前的直接输出即可;
首先,3 2
3是全排列:
123 132
213 231
312 321
即第一位为1-3,每个有2!=2个,第二位为剩余的两个的排序,如果给剩余的标号为0,1,则为01,10;
4 4
1234 1243 1324 1342 1423 1432
2134 2143.。。。
什么规律?
第i位为前i-1位排列后剩下的说的全排列;如,第一位为1,后3位为234的全排列;所以想确定第一位为1-4的哪一个,只需
m/3!即可,求下一位时m=m%3!;
这就好弄了,一位一位的求出来就行了。
但n==1000啊!!求n!???????突然发现m却只有10000啊;这说明只许求前10000个的n排列,判断知道,8!>10000;
即只有后8位在变,8位之前的直接输出即可;
#include<stdio.h>
#include<string.h>
int a[10]={1,1,2,6,24,120,720,5040};
int b[10];
int main ()
{
int n,m,i,k,t;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=1;i<=n-8;i++)
printf("%d ",i);
for(k=0;i<=n;i++)
b[k++]=i;
for(i=n>8?8:n;i>1;i--)
{
t=(m-1)/a[i-1];
for(k=0;k<8&&k<n;k++)
{
if(b[k]&&t==0)
{
printf("%d ",b[k]);
b[k]=0;
break;
}
else if(b[k])
t--;
}
m=(m-1)%a[i-1]+1;
}
for(k=0;k<8&&k<n;k++)
if(b[k])
printf("%d\n",b[k]);
}
return 0;
}