小猴子下落
- 描述
-
有一顆二叉樹,最大深度爲D,且所有葉子的深度都相同。所有結點從左到右從上到下的編號爲1,2,3,·····,2的D次方減1。在結點1處放一個小猴子,它會往下跑。每個內結點上都有一個開關,初始全部關閉,當每次有小猴子跑到一個開關上時,它的狀態都會改變,當到達一個內結點時,如果開關關閉,小猴子往左走,否則往右走,直到走到葉子結點。
一些小猴子從結點1處開始往下跑,最後一個小猴兒會跑到哪裏呢?
- 輸入
- 輸入二叉樹葉子的深度D,和小猴子數目I,假設I不超過整棵樹的葉子個數,D<=20.最終以 0 0 結尾
- 輸出
- 輸出第I個小猴子所在的葉子編號。
- 樣例輸入
-
4 2
-
3 4 0 0
- 樣例輸出
-
12 7
-
思路:
-
運用性質:二叉樹,一個結點的左孩子2*k,右孩子 2 * k + 1,父親 k/2
-
模擬,不需要建樹,只需建一個一維數組,表示開關狀態
-
由於走到下一個結點的時候結點代號就改變了,所以就先改變結點開關狀態,再走下一層
-
代碼如下:
-
#include<stdio.h> #include<string.h> const int MAXD = 20; int s[1 << MAXD];//開關 int main() { int D, I; while(scanf("%d%d", &D, &I) && D && I) { memset(s, 0, sizeof(s)); int k, n = (1 << D) - 1; for(int i = 0; i < I; i++){ k = 1; for(;;){ s[k] = !s[k]; //先改變開關的狀態 if(s[k]) k = k * 2 ;//如果開關狀態改變後是開着的,說明沒改之前是關着的,走下一層的左孩子 else k = k * 2 + 1; //s[k] = !s[k]; if(k > n)//越界 break; } } printf("%d\n", k / 2);//輸出越界了的結點的父親 } return 0; }