01數字排序 題解

2021-10-10 02:19:37 字數 2160 閱讀 3929

題目描述

現有乙個公升序排序的n位的二進位制數。

這些二進位制數包含所有長度為n且這個二進位制數中1的位數的個數小於等於l(l<=n)的數。

你需要輸出的是第i(輸入的i確保1<=i<2的n次冪)小的,長度為n,且1的位數的個數小於等於l的那個二進位制數,如果還是看不懂的,可以看樣例解釋。

(比如:001001這樣的數字,n=6,含有位數為1的個數為2)。

n<=31

輸入共一行,用空格分開的三個整數n,l,i。

輸出共一行,輸出滿足條件的第i小的二進位制數。

樣例輸入

5 3 18

樣例輸出

10010提示

樣例解釋:

1 00000

2 00001

3 00010

4 00011

5 00100

6 00101

7 00110

8 00111

9 01000

10 01001

11 01010

12 01011

13 01100

14 01101

15 01110

15 01111 (有四個1,不符條件,pass掉)

16 10000

17 10001

18 10010

19 10011

step1:暴力

列舉答案即可。

step:優化

不難得出,在長度為 x

xx 出現 y

yy 個 1

11 的總數為

f (x

,y)=

∑i=0

ycxi

f(x,y)=\sum^y_c^i_x

f(x,y)

=i=0

∑y​c

xi​利用這個公式我們從高到低進行確定這位是取 0

00 還是 1

11 。(類似於康托展開的感覺)

最後記得計算排列的時候要卡精度。

tips: cyx

=cyy

−x

c^x_y=c^_y

cyx​=c

yy−x

​32!

>262

−1

32!>2^-1

32!>26

2−1

typedef

unsigned

long

long ull;

ll c

(int x,

int y)

for(

;j<=y;j++

) res/

=(ull)j;

return res;

}

最後是**:

#include

using

namespace std;

typedef

long

long ll;

typedef

long

long type;

inline type read()

if(flag)

return

-sum;

return sum;

}ll k,n,l;

intcheck

(int x)

return1;

}typedef

unsigned

long

long ull;

ll c

(int x,

int y)

for(

;j<=y;j++

) res/

=(ull)j;

return res;

}ll f

(int x,

int y)

void

printx

(int x)

}int ans[

139]

,tmp;

intmain()

else

for(

int i=n;i>=

1;i--

)printf

("%d"

,ans[i]);

return0;

}

統計數字 快速排序題解

某次科研調查時得到了n個自然數,每個數均不超過1500000000 1.5 109 已知不相同的數不超過10000個,現在需要統計這些自然數各自出現的次數,並按照自然數從小到大的順序輸出統計結果。輸入第1行是整數n,表示自然數的個數 第2 n l每行乙個自然數。輸出共m行 m為n個自然數中不相同數的...

題解 01揹包

描述 乙個旅行者有乙個最多能裝 m 公斤的揹包,現在有 n 件物品,它們的重量分別是w1,w2,wn,它們的價值分別為c1,c2,cn,求旅行者能獲得最大總價值。輸入第一行 兩個整數,m 揹包容量,m 200 和n 物品數量,n 30 第2 n 1行 每行二個整數wi,ci,表示每個物品的重量和價值...

01揹包 題解

略略 我們的狀態陣列f i j f i j f i j 指在揹包有j jj的容量,只有前i ii件物品時的最大價值 由於每種物品只有選與不選兩種情況 所以如果容量允許,那麼f i j f i j f i j 只有兩種選擇 選擇第i ii件物品,或不選 狀態轉移方程見 然鵝,我們可以使用一些奇妙的手段...