題目:
將一系列給定數字插入一個初始爲空的小頂堆H[]。隨後對任意給定的下標i,打印從H[i]到根結點的路徑。
輸入格式:
每組測試第1行包含2個正整數N和M(≤1000),分別是插入元素的個數、以及需要打印的路徑條數。下一行給出區間[-10000, 10000]內的N個要被插入一個初始爲空的小頂堆的整數。最後一行給出M個下標。
輸出格式:
對輸入中給出的每個下標i,在一行中輸出從H[i]到根結點的路徑上的數據。數字間以1個空格分隔,行末不得有多餘空格。
輸入樣例:
5 3
46 23 26 24 10
5 4 3
輸出樣例:
24 23 10
46 23 10
26 10
分析與思路:
此題自己開始寫了,也是建堆,插入,再輸出,弄了半天,十分煩躁,然後就開始去Internet尋找些呀,看看有沒有什麼好的呢,到mooc時發現小白專場又有這道題哈,然後就看視頻看了一遍,我好想吐槽呀,我咋就這麼蠢嘞,用數組可以了呀,還傻逼樣的去建堆,因此有些時候不要看到樹,堆得時候應該先想想是否可以不用建樹,建堆,而不是盲目的立刻就寫,有時候採用數組就可以更好地解決,這題用數組存儲數據多好呀。創建堆,插入都是很簡單的。[鏈接]
code:
#include <iostream>
using namespace std;
#define MAXN 1001
#define MINH -10001
void Create();
void Insert(int x);
int H[MAXN], size; // 全局變量, 堆的數組和大小
int main()
{
int N, M, x, j;
cin>>N>>M; /* 輸入第一行的兩個數 */
Create(); /* 堆初始化 */
for(int i=0; i<N; i++) { /*以逐個插入方式建堆 */
cin>>x;
Insert(x);
}
for(int k=0; k<M; k++) {
cin>>j;
cout<<H[j];
while (j>1) { /*沿根方向輸出各結點*/
j /= 2;
cout<<" "<<H[j]; /*輸出結點*/
}
cout<<endl;
}
return 0;
}
void Create()
{
size = 0;
H[0] = MINH;
}
void Insert(int x)
{
if(size==1000) // 堆已滿
return;
int i;
size++; // 堆大小加一
for (i = size; H[i/2] > x; i/=2) {
H[i] = H[i/2];
}
H[i] = x;
}