标签:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2062
1 1 2 1 2 2 2 3 2 4 3 10
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;
}
标签:
原文地址:http://blog.csdn.net/wlxsq/article/details/51365588