杭电1027

本题就是求全排列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位之前的直接输出即可;



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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值