小球下落 (二叉樹的應用)

2021-09-07 15:29:39 字數 2322 閱讀 4501

有一棵二叉樹,最大深度為d,且所有葉子的深度都相同。所有結點從上到下從左到右編號為1,2,3,...,2^d-1。在結點1處放乙個小球,它會往下落。每個內結點上都有乙個開關,初始全部關閉,當每次有小球落到乙個開關上時,它的狀態都會改變。當小球到達乙個內結點時,如果該結點上的開關關閉,則往左走,否者往右走,直到走到葉子結點。

一些小球從結點1處依次開始下落,最後乙個小球將會落到**呢?輸入葉子深度d和小球個數i,輸出第i個小球最後所在的葉子編號。假設i不超過整棵樹的葉子個數(即2^(d-1))。d<=20。輸入最多包含1000組資料。

樣例輸入:

4 23 4

10 1

2 28 128

16 12345

樣例輸出:127

5123

25536358

[分析]

不難發現,對於乙個結點k,它的左兒子、右兒子的編號分別是2k和2k+1。所以方法[1]可以模擬程式輸出結果。但是這種方法的缺點是:運算量太大,由於小球個數i可以高達2^(d-1),每個測試資料下落總層數可能會高達2^19*(20-1)=9961472。所以效率比較低。

考慮方法[2],每個小球都會落在根結點上,因此前兩個小球必然是乙個在左子樹,乙個在右子樹。一般地,只需看小球的編號的奇偶性,就能知道它是最終在哪棵子樹中。對於那些落入根結點左子樹的小球來說,只需知道該小球是第幾個落在根的左子樹里的,就可以知道它下一步往左還是往右了。以此類推,直到小球落到葉子上。當i是奇數時,它是往左走的第(i+1)/2個小球;當i是偶數時,它是往右走的第i/2個小球。這樣,可以直接模擬最後乙個小球的路線。這樣,程式的運算量就與小球編號無關了,而且節省了乙個巨大的陣列tree,程式的效率很高。

[1] 通過模擬程式輸出結果。

[cpp]view plain

copy

#include 

#include 

#include 

#include 

usingstd::string;  

constintmanx=20;  

inttree[1<intmain()  

29.         }  

30.         end=clock();  

31.         printf("%d/n",k/2);// the number of node before out of range  

32.         printf("time used: %lfs/n",(double)(end-beg)/clocks_per_sec);  

33.     }  

34.return0;  

35. }  

36. /* 

37. 16 65535 

38. 49151 

39. time used: 0.016000s 

40. */  

[2]  根據規律輸出結果。

[cpp]view plain

copy

#include 

#include 

#include 

#include 

usingstd::string;  

intmain()  

23.else24.               

29.         }  

30.         end=clock();  

31.         printf("%d/n",k);  

32.         printf("time used: %lfs/n",(double)(end-beg)/clocks_per_sec);  

33.     }  

34.return0;  

35. }  

36. /* 

37. 16 65535 

38. 49151 

39. time used: 0.000000s 

40. */  

小球下落(二叉樹)

有一棵二叉樹,最大深度為d,且所有葉子的深度都相同。所有結點從上到下從左到右編號為1,2,3,2 d 1。在結點1處放乙個小球,它會往下落。每個內結點上都有乙個開關,初始全部關閉,當每次有小球落到乙個開關上時,它的狀態都會改變。當小球到達乙個內結點時,如果該結點上的開關關閉,則往左走,否者往右走,直...

二叉樹之小球下落

題目 有一顆二叉樹,最大深度為d,且所有葉子的深度都相同。所有節點從上到下從左到右編號為1,2,3,2 d 1。在節點1處放置乙個小球,它會往下落。每個內節點上都有乙個開關,初始全都關閉,當每次有小球落到乙個開關上時,他的狀態都會改變。當小球到達乙個內節點時,如果該節點上的開關關閉,則往左走,否則往...

二叉樹的編號優化 小球下落

參考 演算法競賽入門經典 每個小球都會落在根節點上,因此前兩個小球必然是乙個在左子樹,乙個在右子樹。一般,只需要知道小球編號的奇偶性,就能知道它是最終在哪棵子樹中。對於那些落入根結點左子樹來說,只需知道該小球是第幾個落在根的左子樹里的,就可以知道它下一步該往左還是往右了。以此類推,直到小球落到葉子結...