意甲冠軍:查找集合{1,2,3...n}第一m一個 排列子。
收集的線索所行的大小。
? ? ? ? ? 例兩個元素的排列子集合按字典樹排列是:{1}, {1,2}, {2}, {2,1};
解法:一個一個元素來確定,每次把剩余的元素按大小順序排列在num中,然后依據排列組合原理直接計算下一個位置的元素的大小。直到排列數為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; }
版權聲明:本文博客原創文章,博客,未經同意,不得轉載。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

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