日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

(完全二叉树编号)小球下落

發(fā)布時間:2025/3/12 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 (完全二叉树编号)小球下落 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目

有一棵二叉樹,最大深度為D,且所有的葉子深度都相同。所有結(jié)點從上到下從左到右編號為1,2,3,…,2eD-1。在結(jié)點1處放一個小球,它會往下落。每個結(jié)點上都有一個開關(guān),初始全部關(guān)閉,當(dāng)每次有小球落到一個開關(guān)上時,它的狀態(tài)都會改變。當(dāng)小球到達一個內(nèi)結(jié)點時,如果該結(jié)點的開關(guān)關(guān)閉,則往上走,否則往下走,直到走到葉子結(jié)點,如下圖所示。

一些小球從結(jié)點1處依次開始下落,最后一個小球?qū)涞侥睦锬?#xff1f;輸入葉子深度D和小球個數(shù)I,輸出第I個小球最后所在的葉子編號。假設(shè)I不超過整棵樹的葉子數(shù);D<=20。輸出最多包含1000組數(shù)據(jù)。
樣例輸入:
4 2
3 4
10 1
2 2
8 128
16 12345
樣例輸出:
12
7
512
3
255
36358

分析與解答

<0>.給定一顆2^d個結(jié)點的完全二叉樹,如果把結(jié)點從上到下從左到右編號,則結(jié)點k的左右子結(jié)點編號分別為2k,2k+1
<1>.根據(jù)觀察,對于根結(jié)點,小球編號為奇數(shù)落在左子樹,偶數(shù)落在右子樹
<2>.每個節(jié)點都可以看成根結(jié)點,并且與他兩個子結(jié)點組成一個新的二叉樹
<3>.根據(jù)根結(jié)點1,找規(guī)律發(fā)現(xiàn),如果小球編號為奇數(shù),他是往左走的第(i+1)/2個小球,如果小球編號為偶數(shù),他是往右走的第i/2個小球。
<4>.如果把每個子節(jié)點看成一個根結(jié)點,那么每個結(jié)點的小球也滿足3的規(guī)律
<5>.第i個小球,從結(jié)點編號為k的地方下落,如果i為奇數(shù),那么此時等價于第(i+1)/2個小球,從結(jié)點編號為k*2的地方下落,如果i為偶數(shù),那么此時等價于第i/2個小球,從結(jié)點編號為k*2+1的地方下落,然后通過<1>,我們就知道他下一步是向左還是向右走
<6>.二叉樹深度為d,小球下落d-1次,每循環(huán)一次,我們就知道他落在哪,下一步怎么走,如果循環(huán)d-1次,剛好走到最后的葉子結(jié)點,此時知道他落在哪,輸出k就行

代碼:

#include<cstdio>int main(){int d,I;while(scanf("%d%d",&d,&I)==2){int k=1;for(int i=0;i<d-1;++i){if(I%2){k=k*2;I=(I+1)/2;}else {k=k*2+1;I/=2;}}printf("%d\n",k);} }

方法二:
利用模擬,二叉樹編號

#include<cstdio> #include<cstring> const int maxd =20; int s[1<<maxd]; int main(){int D,I;while(scanf("%d%d",&D,&I)){memset(s,0,sizeof(s));int k,n =(1<<D)-1;//n是最大節(jié)點編號 for(int i=0;i<I;++i){k=1;for(;;){s[k]!=s[k];//每次開關(guān)變化 k=s[k]?k*2:k*2+1;//根據(jù)開關(guān)狀態(tài)選擇下落方向 if(k>n) break;//出界了 }}printf("%d\n",k/2);//出界之前葉子編號 } }

總結(jié)

以上是生活随笔為你收集整理的(完全二叉树编号)小球下落的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。