HDU 2062 Subset sequence[排列組合]

題幹

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

題解

大神講解的已經很清楚了(走你),我只寫我的總結:

/**
*整個題目的解題關鍵就在於,要學會用一個數組去搞排列組合,通過
*不斷的維護和更新數組(這個題目維護s[]數組),
*並且通過一定的公式(這個題目的公式是第22行和第23行的代碼)計算不斷輸出,
*才能得出最終結果
*總結:
*1,注意變量的類型是否正確,如果沒有給出,則一定要精確確定數據範圍,
*不然WA沒商量,特殊情況下,就算給了變量類型,也可能給的不對,要自己確定清楚
*2,學會通過維護數組+固定公式去搞排列組合
*/
#include<cstdio>
int s[21]={0};
void del(int pos){
  for(int i=pos;i<21;i++)s[i]=s[i+1];
}

int main(){
  int n;
  __int64 m;//題目中沒有給出m的取值範圍,但是,隱含着m是一個64位整數
  __int64 f[21]={0,1},g[21]={0,1};
  for(int i=2;i<21;i++){
    f[i] = i * (f[i-1]+1);
    g[i] = f[i]/i;//g[20]是一個64位整數,所以g[]數組應該用64位整數的
    //printf("%I64d\n",g[i]);
  }
  while(~scanf("%d%I64d",&n,&m)){
     for(int i=0;i<21;i++)s[i]=i;
     __int64 gsize = g[n];
     while(m>0&&n>0){
        if(m<=f[n]){
          int pos = m%gsize ? m/gsize + 1 : m/gsize;
          printf("%d",s[pos]);
          del(pos);
          m = m - (pos-1)*gsize -1;
          gsize = g[--n];
          putchar(m>0 ? ' ' : '\n');
        }
     }
  }
}
發佈了40 篇原創文章 · 獲贊 0 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章