Subset sequence
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 11478 Accepted Submission(s): 4888
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
对所有的子序列按字典顺序排列
子集里元素考虑顺序了,
题意:
1.一个规则的数组,从1...n的
2.对这个数组进行有规则的排序
例如 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
3.问你,给你一个m,让你输出该数组第几个的表达形式
既然分组了,要确定m在第几组里,所以要求每一组的子集个数
分组后每组子集个数为c[n]
总子集数为 f[n]
所以c[n]=f[n]/n
f[n]=n*(f[n-1]+1)
∴c[n] = n[f[n-1] + 1] / n = f[n-1] + 1
∵f[n-1] = (n-1) * c[n-1]
∴c[n] = (n-1) * c[n-1] + 1
程序步骤实例解说:
n=3,m=10时,有
{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}
- 求得t=2,先输出第2组首元素2
- 再去掉前面不需要的分组,和首元素,剩下唯一一组子集:因此此时m-=((t-1)*c[n]+1)=4
//{}
{1}
{1, 3}
{3}
{3, 1} - 然后再分成两组, t=m/c[n]+(m%c[n]>0?1:0)求得当前在第t=2组
输出第2组首元素3,再去掉前面不需要的分组,和首元素,剩下唯一一组子集
因此此时m-=((t-1)*c[n]+1)=1
//{}
{1} - 然后剩最后一组, t=m/c[n]+(m%c[n]>0?1:0)求得当前在第t=1组
输出第1组首元素1,和首元素,剩下唯一一组子集
{}//空集
因此此时m-=((t-1)*c[n]+1)=0
将该子集的下一个元素到最后一个的值+1,注意这个规律:在第i组,首元素为i,删除首元素后,在第i个子集后首元素均变大+1.
#include<iostream>
using namespace std;
int main()
{
int i;
int n; //一共多少元素
int t; //所求集合位于分组后的第几组
__int64 m; //位于第几个元素
__int64 c[21]={0}; //分组后每组个数
int s[21]; //将子集按字典序分组后每组的初始首元素
for(i=1;i<21;i++)
{
c[i]=c[i-1]*(i-1)+1;
}
while(cin>>n>>m)
{
for(i=0;i<21;i++)
{
s[i]=i;
}
while(n>0&&m>0)
{
t=m/c[n]+(m%c[n]>0?1:0);
if(t>0)
{
cout<<s[t];
for(i=t;i<=n;i++)
{
s[i]=s[i+1];
}
m-=((t-1)*c[n]+1);//减去(t-1组总子集数+1),m变为表示在剩余子集中位于第几个
putchar(m==0?'
':' ');
}
n--;
}
}
return 0;
}