题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2062
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
可以用vector实现康拓逆展开;
代码:
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<vector> #define LL long long using namespace std; int ans[30]; int len=0; LL fac[23]; /* 康拓逆展开已AC void Cantor(int n,LL m) { int N=n; int i,j,vis[23]={0}; while(n--&&m){ LL t=m/fac[n+1]; if(m%fac[n+1]) t+=1; LL k=t; for(i=1;i<=N;i++){ if(!vis[i]){ k--; if(k==0) break; } } vis[i]=1; ans[len++]=i; m-=((t-1)*fac[n+1]+1); } } */ // 用vector实现康拓逆展开 void Cantor(int n,LL m) { vector<int>q; for(int i=1;i<=20;i++){ q.push_back(i); } while(n--&&m){ LL t=m/fac[n+1]; if(m%fac[n+1]) t+=1; ans[len++]=q[t-1]; q.erase(q.begin()+t-1); m-=((t-1)*fac[n+1]+1); } } void f() { fac[0]=0; fac[1]=1; // 注意数据类型; for(int i=2;i<=21;i++){ fac[i]=fac[i-1]*(i-1)+1; } } int main() { f(); LL n,m; //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); cin.sync_with_stdio(false); while(cin>>n>>m){ len=0; Cantor(n,m); for(int i=0;i<len;i++){ if(i<len-1) cout<<ans[i]<<' '; else cout<<ans[i]<<endl; } } return 0; }
时间: 2024-10-09 18:30:16