hdu 2062 Subset sequence

该题的意思为求N个数构成的第M个序列

方法为一层一层往下剥,每次都求出当前序列的第一个数

例如N= 3 时构成的序列为

 1

 1 2

 1 2 3

 1 3

 1 3 2

 2

 2 1

 2 1 3

 2 3

 2  3  1

 3

 3 1

 3 1 2

 3 2

 3 2 1

设两个数构成的序列和为a【2】,则明显可求出a【3】= 3 * (a【2】 + 1) 由此推出a【n】= n * (a【n-1】 +  1);

例如N= 3, M= 8 时,我们可算出t= (M - 1) / ( a[3-1] + 1 ) + 1= 2,  则序列的第一个数为2

然后 可在两个数构成的序列中,求出下一个数的值

代码:

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<limits.h>
using namespace std;
int main()
{
	__int64 a[20];// a[i]表示i个数能构成的序列总个数 
	a[0]= 0;
	a[1]= 1;
	for(int i= 2; i<= 20; i++)
		a[i]= i *(a[i-1] + 1);
	int n;
	__int64 m;
	while(scanf("%d %I64d",&n,&m)!=EOF)
	{
		int hash[21];
		memset(hash,0,sizeof(hash));
		int num= n;//剩余数的个数 
		int flag= 0; 
		while(m)
		{
			int t;
			t= (m-1)/(a[num-1]+1) + 1;// 该序列的第一个数
		//	printf("%d\n",t);
			for(int i= 1,j= 0; i<= n && j<= t; i++)
			{
				if(!hash[i])
				{
					j++;
					if(j==t)
					{
						hash[i]= 1;
						if(flag==0)
						{
							printf("%d",i);
							flag= 1;
						}
						else
							printf(" %d",i);
					}
				}
			}
			m-= (t-1) * (a[num-1]+1);
			m--;
			num--; 
		}
		printf("\n");
	}
return 0;
}


 

 

你可能感兴趣的:(hdu 2062 Subset sequence)