6.小球下落
問題描述:
有一棵二叉樹,最大深度為D,且所有的葉子深度都相同。所有結點從上到下從左到右編號為1,2,3,…,2eD-1。在結點1處放一個小球,它會往下落。每個結點上都有一個開關,初始全部關閉,當每次有小球落到一個開關上時,它的狀態(tài)都會改變。當小球到達一個內(nèi)結點時,如果該結點的開關關閉,則往上走,否則往下走,直到走到葉子結點,如下圖所示。
一些小球從結點1處依次開始下落,最后一個小球?qū)涞侥睦锬兀枯斎肴~子深度D和小球個數(shù)I,輸出第I個小球最后所在的葉子編號。假設I不超過整棵樹的葉子數(shù);D<=20。輸出最多包含1000組數(shù)據(jù)。
樣例輸入:
4 2
3 4
10 1
2 2
8 128
16 12345
樣例輸出:
12
7
512
3
255
36358
分析:二叉樹性質(zhì)的簡單應用
//輸入深度和小球個數(shù)
//確定最大的小球編號、確定葉子起始節(jié)點編號
//重起始節(jié)點開始當前節(jié)點為(n):如果為0則下一個節(jié)點為男2n,否者為2n+1;束條件為:n> 最大葉子節(jié)點。
#include <cstdio>
#include <cstring>
const int maxd = 20;
int s[1<<maxd];
int main() {
int d, t;
while(scanf("%d %d",&d,&t) == 2){
memset(s, 0, sizeof(s));//用于某一塊內(nèi)存的初始化
int max_leaf_node = (1<<d)-1;// 確定最大葉子編號;
int k;
for(int i = 0;i < t;i++){
k=1;
for(;;){
if(s[k] == 0) {
s[k] = 1;
k = k*2;
}
if(s[k] == 1){
s[k] = 0;
k = k*2 + 1;
}
if(k>max_leaf_node) break;
}
}
printf("%d\n",k/2);
}
return 0;
}
測試數(shù)據(jù)
4 2
12
3 4
7
10 1
512
2 2
3
8 128
255
16 12345
36358