問題描述 :
有一棵二叉樹,最大深度爲D,且所有葉子的深度都相同。所有結點從上到下從左到右 編號爲1, 2, 3,…, 2D-1。在結點1處放一個小球,它會往下落。每個內結點上都有一個開關, 初始全部關閉,當每次有小球落到一個開關上時,狀態都會改變。當小球到達一個內結點時,如果該結點上的開關關閉,則往左走,否則往右走,直到走到葉子結點。
如圖所示:
樣式輸入:
4 2
3 4
10 1
2 2
8 128
16 12345
樣式輸出:
12
7
512
3
255
36358
解題思路:
本題原先採用利用數組存儲二叉樹節點,但是會造成大量空間浪費。
所以我們假設只有2個球,深度2第一個球很明顯就落在1號根節點的左子樹上,第二個球落在1號根節點的右子樹上。因此可以推論,只要看球個數的奇偶性,便可以計算出它最終是落在哪個子樹上。如果球的個數是奇數,便落在(num+1)/2的左子樹上。如果球的個數是偶數,便落在num/2的右子樹上。
實現:
import java.util.Scanner;
/**
* 小球落地問題
*
* @Classname BallFall
* @Description TODO
* @Date 2019/8/17 14:50
* @Created zzf
*/
public class BallFall {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//深度
int depth = sc.nextInt();
//第num個球
int num = sc.nextInt();
//初始化
int data = 1;
//計算層數爲1~dapth-1
for (int i = 1; i <= depth - 1; i++) {
//如果有餘數則這個球在左邊,否則在右邊
if (num % 2 == 1) {
//計算,因爲在左邊*2
data *= 2;
//計算下一個標號的位置
num = (num + 1) / 2;
} else {
//計算,右邊比左邊大1
data = data * 2 + 1;
num /= 2;
}
// System.out.println(data);
}
System.out.println(data);
}
}