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

被折叠的 条评论
为什么被折叠?



