南大算法設計與分析課程OJ答案代碼(3)

 

問題 A: 動態中位數問題

時間限制: 1 Sec  內存限制: 8 MB
提交: 866  解決: 102
提交 狀態 算法問答 

題目描述

輸入一組整數a1, a2, …, an ,每輸入一個整數,輸出到此時爲止的中位數。 php

中位數定義:若是數串的大小是偶數 2j,中位數是從小到大排列的第 j 個數;若是數串的大小是奇數 2j+1,中位數是從小到大排列的第 j+1 個數。 c++

輸入

一組整數,數字和數字之間以空格隔開。

輸出

一組整數,數字和數字之間以空格隔開。最後一個數後面也有空格。 算法

第 i 個輸出的整數,是前 i 個輸入的中位數。 函數

樣例輸入

-18 -2 14 -20 -6 7 2 14 11 6 

樣例輸出

-18 -18 -2 -18 -6 -6 -2 -2 2 2 

提示

時間複雜度請不要超過O(nlogn)。
因爲輸入輸出的量會比較大,所以推薦使用c語言中的scanf和printf函數來進行輸入輸出,能比c++中cin和cout節省許多時間。測試

這裏原本有一行提示,可是因爲老師上課不當心說漏嘴了,因而助教狠心地把它註釋掉了 ;spa

/*在處理該問題時,堆結構也許能給你帶來意想不到的幫助。*/.net

 答案

比較尷尬,最近一忙就忘記作了,因此答案沒有通過oj測試,僅供參考(但測試用例一遍過了)翻譯

思路就是維護一個mid值、最大堆(存放比mid小的值)、最小堆(存放比mid大的值),每次讀入一個數,根據兩邊堆的大小來判斷當前值,具體怎麼判斷見代碼註釋,代碼中有關STL中堆的使用操做就很少數了,自行查閱。code

代碼在VS2017上運行,在讀入輸出部分可能須要更改一下,scanf_s改scanf?blog

int main() { vector<int> heap_small;    //這應該是個最大堆,存放着比mid小的元素
    vector<int> heap_big;    //這應該是個最小堆,存放着比mid大的元素
    int mid =0; scanf_s("%d",&mid); printf("%d ",mid); int temp = 0; while (scanf_s("%d",&temp)!=EOF) { if (temp < mid) { if (heap_small.size() == heap_big.size()) { //左側和右側同樣大,將mid放入heap_big中,temp放入heap_small中,而後從heap_small選一個最大的做爲mid
 heap_big.emplace_back(mid); push_heap(heap_big.begin(), heap_big.end(), [](int a, int b) {return b < a; }); heap_small.emplace_back(temp); push_heap(heap_small.begin(),heap_small.end()); pop_heap(heap_small.begin(), heap_small.end()); mid = heap_small.back(); heap_small.pop_back(); }else if (heap_small.size() == heap_big.size() - 1) { //右側比左側多一個,將temp放入heap_small中,而後mid仍是爲中位數
 heap_small.emplace_back(temp); push_heap(heap_small.begin(), heap_small.end()); }else { //左側比右側多一個的狀況應該不會出現
                cout << "wrong" << endl; } } else { if (heap_small.size() == heap_big.size()) { //左側和右側同樣大,將temp放入heap_big中,mid仍是中位數
 heap_big.emplace_back(temp); push_heap(heap_big.begin(), heap_big.end(), [](int a, int b) {return b < a; }); } else if (heap_small.size() == heap_big.size() - 1) { //右側比左側多一個,將mid放入heap_small中,而後將temp放入heap_big中,而後從heap_big選一個最小的做爲mid
 heap_small.emplace_back(mid); push_heap(heap_small.begin(), heap_small.end()); heap_big.emplace_back(temp); push_heap(heap_big.begin(), heap_big.end(), [](int a, int b) {return b < a; }); pop_heap(heap_big.begin(), heap_big.end(), [](int a, int b) {return b < a; }); mid = heap_big.back(); heap_big.pop_back(); } else { //左側比右側多一個的狀況應該不會出現
                cout << "wrong" << endl; } } printf("%d ",mid); } return 0; }

 

問題 B: 非完美二叉樹的高度與直徑

時間限制: 2 Sec  內存限制: 3 MB
提交: 249  解決: 95
提交 狀態 算法問答 

題目描述

記T爲一棵二叉樹,樹中共有n個節點。

定義根節點的深度爲0,其他節點的深度爲其父節點的深度加1。T的高度定義爲其葉節點深度的最大值。

定義樹中任意兩點a和b之間的距離爲其間最短簡單路徑的長度。T的直徑定義爲T中全部點對間距離的最大值。

輸入一棵二叉樹T,請計算它的高度和直徑。

輸入

輸入共三行。

第一行輸入n的值,表示樹中結點的總個數。

第二行爲樹的前序遍歷表示,每一個節點之間用空格隔開。

第三行爲樹的中序遍歷表示,每一個節點之間也用空格隔開。

輸出

輸出共三行。
第一行須要你們輸出一行字符串,它是「我已閱讀關於抄襲的說明」的英文翻譯,即:"I have read the rules about plagiarism punishment"。輸出此行的提交咱們將認爲已經徹底閱讀並瞭解了「關於抄襲的說明」公告並贊成關於抄襲的懲罰措施。
第二行輸出樹的高度。
第三行輸出樹的直徑。



樣例輸入

10 0 1 9 3 8 4 2 7 5 6 3 9 8 1 2 4 0 5 7 6 

樣例輸出

I have read the rules about plagiarism punishment 3 5

提示

分治算法能夠在O(n)的時間內完成相應的計算。

答案

無法提交了,懶得寫了,網上答案挺多的

相關文章
相關標籤/搜索