J - Subset sequence

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

该题意思是找M-th的序列并输出。

首先理解题目中排序规则,以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

按照数字大小顺序排序,

可以发现,输出的序列第一个是m除以n个数的排序数,比如2有2种组合,3每次有5种组合,如果组合数以数组a(n)表示,则有a(n)=(n-1)*a(n-1)+1的规律

剩下的依序输出,比如输入的n和m是3 10,则第一个输出的应当是10/5,考虑到3有5种组合,但是第五种是以1开头的最后一种序列,所以,m=10时,其实是2开头的最后一种序列。若是m=11,虽然m/5=2,但是已经是3开头的序列了,所以,计算第一个输出的数时,应该是t=m/n组合数+m%n组合数?1:0;意思是如果求余不为0,加一,这样就符合实际情况。以此类推,每当输出一个t,应当将t从常数数组内去除,也就是将t之后的数全部提前一位。

代码实现如下,C++

#include <iostream>
using namespace std;
int main()
{
	long long int n, m;
	long long int p[21], a[22];
	p[0] = 0, p[1] = 1;
	for (int i = 2; i < 21; i++)
		p[i] = p[i - 1] * (i - 1) + 1;	
	while (cin >> n >> m)
	{
		for (int i = 0; i <= 21; i++)a[i] = i;
		while (m > 0 && n > 0)
		{
			int t = m / p[n] + (( m % p [n] ) ? 1 : 0);
			cout << a[t];
			for (int i = t; i <= n; i++)
				a[i] = a[i + 1];
			m -= ((t - 1)*p[n] + 1);
			if (m)cout << " ";
			n--;
		}
		cout << endl;
	}
	return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值