2062 Subset sequence
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
参考链接:很妙的递归题(“妙啊”的橘子猫微笑)
最终AC代码如下:
#include <bits/stdc++.h> using namespace std; typedef long long int LL; const int maxn = 22; LL id[maxn]={0}, f[maxn]={0}; bool flag; void getAnser(LL n, LL m){ if(m==0) return ; //当前元素为空集 达到临界点 LL pos=(m-1) / (f[n-1]+1) + 1; //加 1 是因为下标从1开始 f[n-1]+1 表示该组的元素个数 m-1保证除后的结果在 0~n-1范围 if(flag) printf(" "); else flag = true; printf("%lld", id[pos]); id[pos] = 99; sort(id+1, id+n+1); getAnser(n-1, (m-1) % (f[n-1]+1)); //(m-1) % (f[n-1]+1) 结果若为 0 则表示下一元素为空集 } int main(){ LL i, n, m; for(i=1; i<maxn; i++) f[i] = (f[i-1]+1) * i; while(scanf("%lld %lld", &n, &m) != EOF){ flag = false; //记录第一个输出的数字 for(i=1; i<=n; i++) id[i] = i; getAnser(n, m); printf("\n"); } return 0; }