小猴子下落

小猴子下落

時間限制:3000 ms  |  內存限制:65535 KB
難度:3
描述

有一顆二叉樹,最大深度爲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;
}


發佈了84 篇原創文章 · 獲贊 8 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章