HDU2062(Subset sequence)

本文介绍了一个算法问题,即如何从给定的整数集合中找到第m个字典序子序列。通过递推预计算各数字的子序列数量,利用除法确定目标子序列中的首位数字,再递归处理剩余位数,最终输出指定序号的子序列。

Subset sequence

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6325    Accepted Submission(s): 2975


Problem Description
Consider the aggregate An= { 1, 2, …, n }. For example, A1={1}, A3={1,2,3}. A subset sequence is defined as a array of a non-empty subset. Sort all the subset sequece of An in lexicography order. Your task is to find the m-th one.
 

Input
The input contains several test cases. Each test case consists of two numbers n and m ( 0< n<= 20, 0< m<= the total number of the subset sequence of An ).
 

Output
For each test case, you should output the m-th subset sequence of An in one line.
 

Sample Input
1 1 2 1 2 2 2 3 2 4 3 10
 

Sample Output
1 1 1 2 2 2 1 2 3 1
这个题目就是给你n个数字 然后给你个m 让你求n个数全排列(按照字典序)中第m个是什么顺序,然后输出。
本来只看到了n等于20 直接DFS 然后实例一过 就提交了 后来超时 后来想了想20全排列估计能出来十亿的数据,DFS肯定超时,后来看了看大佬的方法。
大佬博客:http://blog.youkuaiyun.com/lianqi15571/article/details/8877014
里面有详细的推理过程
#include<stdio.h>

int main()
{
	long long n,t;
	long long a[25]={0};//记录每个数字拥有的全排列的子集个数 
	long long b[25];//记录当前存在哪些数字
	for(int i=1;i<=20;i++)//1-20 先全排列 
	{
		a[i]=i*(a[i-1]+1);
	}
	while(scanf("%lld %lld",&n,&t)!=EOF)
	{
		for(int i=1;i<=n;i++)
			b[i]=i;
		while(n>0 && t>0)
		{	
			long long temp=t/(a[n]/n)+(t%(a[n]/n)>0?1:0);//先分析出来第一个数字是什么  看看在第几堆 
			if(temp>0)//如果存在 
			{
				printf("%lld",b[temp]);//输出当前记录的数字 
				for(int i=temp;i<n;i++) //刷新还存在什么数字 
					b[i]=b[i+1]; 
				t=t-(temp-1)*(a[n]/n)-1;   //用应该是第几个集合----(t-1)*一个数字应该有的集合数  
				if(t>0)
					printf(" ");
				else
					printf("\n");
			}
			n--;
		}
	}
	return 0;
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值