zoukankan      html  css  js  c++  java
  • HDU 2062:Subset sequence(思维)

    Subset sequence

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

    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
    

    题意

    对于一个序列An={1,2,3...n}A_n={1,2,3...n}A1={1},A3={1,2,3}A_1={1},A_3={1,2,3},我们称一个非空子集元素的排列为一个子集序列。对所有的子集序列按字典顺序排序。求出第m个子序列

    思路

    首先要求出AnA_n有多少子集:
    n=1n=1时,子集个数为1个
    n=2n=2时,子集个数为4个
    n=3n=3时,子集个数为15个
    子集的个数满足F(n)=(F(n1)+1)×nF(n)=(F(n-1)+1) imes n
    n=3n=3为例,将AnA_n全部列出来可得:
    {1},{1,2},{1,2,3},{1,3},{1,3,2}{1},{1,2},{1,2,3},{1,3},{1,3,2}
    {2},{2,1},{2,1,3},{2,3},{2,3,1}{2},{2,1},{2,1,3},{2,3},{2,3,1}
    {3},{3,1},{3,1,2},{3,2},{3,2,1}{3},{3,1},{3,1,2},{3,2},{3,2,1}
    例如:
    在计算样例3 10时,先计算第10个子集位于第几行(以哪个数字开头)。输出该数字后,把该数字从AnA_n中删除,然后删掉第二行之前的所有子集,和第二行的第一个子集{2}{2}mm变成在剩余集合中的子集的位置。重复操作,至到mm小于0为止

    AC代码

    /*
    * @Author: WZY
    * @School: HPU
    * @Date:   2018-11-11 15:02:40
    * @Last Modified by:   WZY
    * @Last Modified time: 2018-11-11 16:06:05
    */
    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <math.h>
    #include <limits.h>
    #include <map>
    #include <stack>
    #include <queue>
    #include <vector>
    #include <set>
    #include <string>
    #include <time.h>
    #define ll long long
    #define ull unsigned long long
    #define ms(a,b) memset(a,b,sizeof(a))
    #define pi acos(-1.0)
    #define INF 0x7f7f7f7f
    #define lson o<<1
    #define rson o<<1|1
    #define bug cout<<"---------"<<endl
    #define debug(...) cerr<<"["<<#__VA_ARGS__":"<<(__VA_ARGS__)<<"]"<<"
    "
    const double E=exp(1);
    const ll maxn=1e6+10;
    const int mod=1e9+7;
    using namespace std;
    // F[n]=(F[n-1]+1)*n
    // 计算n对应的子集的个数
    ll F(ll n)
    {
    	if(n<=1)
    		return n;
    	return (F(n-1)+1)*n;
    }
    int main(int argc, char const *argv[])
    {
    	ios::sync_with_stdio(false);
    	#ifndef ONLINE_JUDGE
    	    freopen("in.txt", "r", stdin);
    	    freopen("out.txt", "w", stdout);
    	    double _begin_time = clock();
    	#endif
    	ll n,m;
    	ll a[30];	
    	while(cin>>n>>m)
    	{
    		for(int i=1;i<30;i++)
    			a[i]=i;
    		int flag=0;
    		while(m>0)
    		{
    			ll k=F(n-1)+1;	//记录每行有多少个集合
    			int res=m/k+1;	//记录在第几行
    			if(m%k==0)		//在上一行
    				res--;
    			if(flag)
    				cout<<" ";
    			cout<<a[res];
    			for(int i=res;i<=n;i++)
    				a[i]=a[i+1];
    			m-=k*(res-1)+1;
    			n--;
    			flag++;
    		}
    		cout<<endl;
    	}
    	#ifndef ONLINE_JUDGE
    	    double _end_time = clock();
    	    printf("time = %lf ms.", _end_time - _begin_time);
    	#endif
    	return 0;
    }
    
  • 相关阅读:
    快讯:优酷四季度净盈余570万美元
    陈诉称谷歌Apps受大企业欢迎 或对微软构成要挟
    Bus.fm:有颜色的“巴士电台”
    摩根大通预计全球PC市场疲软 中国为主因
    中国联通首批沃Phone终端将于3月上市销售
    酷派将推800元Android智好手机推行3G终端
    谷歌预计将来几年在线告白局限打破1000亿美元
    Facebook与日本电通协作展开告白营销业务
    动静称苹果2日将推出小企业手艺支撑办事
    C# 调用C++生成的dll
  • 原文地址:https://www.cnblogs.com/Friends-A/p/10324329.html
Copyright © 2011-2022 走看看