UVa679小球下落(二叉樹的編號)

2022-07-06 15:36:08 字數 1484 閱讀 4911

樹是n個元素的有限集合,不再是序列,其中\(n>=0\)。樹可以看成無共享純廣義表。

二叉樹的3個要素,根結點,左子樹和右子樹。二叉樹不是樹,樹的兩個要素是根結點和子樹森林。

無論線性結構還是樹形結構,第乙個元素都沒有前驅。線性結構的最後乙個元素都沒有後繼,樹形結構有多個葉子結點,都沒有後繼。對於中間的一般元素,樹形結構有乙個前驅,多個後繼,線性結構有乙個前驅(無共享),乙個後繼。

完全二叉樹是從上到下從左到右依次排過來,整棵樹有唯一的深度取值。豐滿二叉樹是每一層都排滿的完全二叉樹,有\(2^i-1\)個結點,每層的結點數目是\(2^\)個,其中i是深度。

完全二叉樹的從上到下從左到右編號上有規律和結論:編號為1,沒雙親,不為1就有雙親;\(2i>n\),沒有左孩子,否則就是左孩子;\(2i+1>n\),沒有右孩子,否則就是右孩子。

採用順序儲存,完全二叉樹不浪費空間,各種運算簡單,由上述性質,求雙親求孩子均為常量演算法。

模擬對於這道題目來說,可以模擬小球下落的過程。題目告訴了最大深度為d,所有葉子深度都相同,就告訴了這是一棵豐滿二叉樹,初始所有結點的開關全部關閉。如果把0當作關閉,1當作開啟,那麼當小球到達乙個結點時,就是先走再改變狀態。判斷,如果是關閉,往左走,如果是開啟就往右走,直到走到葉子結點。

題目給定深度d和小球個數i,由深度d就可以求出最大的小球編號n = \(2^d-1\),接下來就利用上述性質進行模擬。

深度不超過20,編號最大是2的20次方-1,接近1000000的結點個數。

表示2的次方可以不用cmath裡的pow(),而是用二進位制計算,用1來移位。邏輯運算布林非改變開關狀態。

從這個資料範圍以及多組測試資料來看,肯定會超時2 ≤ d ≤ 20, and 1 ≤ i ≤ 524288.

#include #include #include #include using namespace std;

const int maxn = 1000010;

int s[maxn];

int d, i;

int main()

memset(s, 0, sizeof(s));

int n = (1《只看乙個小球

例子,4個小球裡面就有2個往左2個往右。也就對應了2個來到左孩子,2個來到右孩子,改變孩子結點的狀態。

第1個小球是第1個往左的,第2個小球是第乙個往右的,第3個小球是第2個往左的,第4個小球是第2個往右的。

所以把走小球變成走深度就可以了,只看最後乙個小球。

這樣不僅節省大大時間,而且節省空間。

#include #include #include #include using namespace std;

int d, i;

int main()

int n = (1<> 1;

} else

} printf("%d\n", k);

}return 0;

}

UVa679 小球下落(樹)

給下落的深度和小球個數,小球依次下落,結點有個開關,每到乙個結點,開關關向左,開向右 一開始想到了簡單模擬,結果超時 include include include define maxn 20 using namespace std int s 1 printf d n now 2 return ...

UVa 679 小球下落 二叉樹的編號

在結點1處放乙個小球,它會往下落。每個內結點上都會有乙個開關,初始全部關閉,當每次有小球落到乙個開關上時,狀態都會改變。當小球到達乙個結點是,如果結點上的開關關閉,則往左走,否則往右走,直到走到葉子的結點,如圖。分析 對於乙個結點k,其左結點和右結點分別為2k和2k 1。小球落到結點處,先改變,後選...

UVa679 完全二叉樹編號

這題我也是用了兩種方法,第一種比較常規,但超時,第二種比較討巧 運用完全二叉樹的性質,對於結點k,左子結點編號2k,右子結點編號2k 1,用乙個陣列表示當前每個結點狀態,然後模擬每個小球的下落過程 include using namespace std const int maxdeep 20 in...