意甲冠軍:查找集合{1,2,3...n}第一m一個(gè) 排列子。
收集的線索所行的大小。
? ? ? ? ? 例兩個(gè)元素的排列子集合按字典樹排列是:{1}, {1,2}, {2}, {2,1};
解法:一個(gè)一個(gè)元素來確定,每次把剩余的元素按大小順序排列在num中,然后依據(jù)排列組合原理直接計(jì)算下一個(gè)位置的元素的大小。直到排列數(shù)為0停止;
代碼:
/****************************************************** * author:xiefubao *******************************************************/ #pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <vector> #include <algorithm> #include <cmath> #include <map> #include <set> #include <stack> #include <string.h> //freopen ("in.txt" , "r" , stdin); using namespace std; #define eps 1e-8 const double pi=acos(-1.0); typedef long long LL; const int Max=21; const int INF=1000000007; LL A[Max][Max]; LL sum[Max]; void init() { for(int i=0; i<Max; i++) for(int j=0; j<=i; j++) A[i][j]=j?A[i-1][j-1]*j+A[i-1][j]:1; for(int i=0; i<Max; i++) for(int j=0; j<=i; j++) sum[i]+=A[i][j]; } int n; LL m; int num[Max]; int main() { init(); while(scanf("%d%I64d",&n,&m)==2) { for(int i=1; i<=n; i++) num[i]=i; int len=n; int t=(m-1)/sum[len-1]+1; printf("%d",num[t]); m-=(t-1)*sum[len-1]+1; for(int k=t; k<=len-1; k++) num[k]=num[k+1]; len--; while(m) { int t=(m-1)/sum[len-1]+1; printf(" %d",num[t]); m-=(t-1)*sum[len-1]+1; for(int k=t; k<=len-1; k++) num[k]=num[k+1]; len--; } puts(""); } return 0; }
版權(quán)聲明:本文博客原創(chuàng)文章,博客,未經(jīng)同意,不得轉(zhuǎn)載。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
