Week5 HomeWork A 最大矩形 單調棧

2021-10-04 09:11:55 字數 2164 閱讀 1560

演算法/思路分析

**

給乙個直方圖,求直方圖中的最大矩形的面積。例如,下面這個中直方圖的高度從左到右分別是2, 1, 4, 5, 1, 3, 3, 他們的寬都是1,其中最大的矩形是陰影部分。

輸入包含多組資料。每組資料用乙個整數n來表示直方圖中小矩形的個數,你可以假定1 <= n <= 100000. 然後接下來n個整數h1, …, hn, 滿足 0 <= hi

<= 1000000000. 這些數字表示直方圖中從左到右每個小矩形的高度,每個小矩形的寬度為1。 測試資料以0結尾。

對於每組測試資料輸出一行乙個整數表示答案。

7 2 1 4 5 1 3 3

4 1000 1000 1000 1000

0

8

4000

本題顯然只需要找到每個頂點的左右第乙個高度小於當前頂點的端點,即可用ans_s= h * length 計算矩形面積。

若直接線性搜尋,o(n2) 會tle(資料範圍為1e5)。

這裡使用一種資料結構:單調棧。顧名思義,該資料結構能夠維持棧內元素出棧時遞增/遞減。本題即可利用單調遞增棧的性質找出左側/右側第乙個高度小於當前頂點的端點。具體而言,記錄每個頂點的編號和高度。正向遍歷:將頂點依次放入單調棧,遇到棧頂端點高度大於將入棧端點高度時,表示該入棧端點為該棧頂端點矩形的右端點,之後彈出棧頂元素,繼續向後操作。反向遍歷時與正向遍歷類似,只需將頂點按照逆序依次放入即可。注意每次遍歷完後,棧內可能會有剩餘元素,剩餘元素的右/左端點即為邊界(n/-1)。另外長度計算時需注意,我們記錄的左端點和右端點其實比實際的小/大1,例:記l = 4,r = 8,實際上應該為ll = 5,rr = 7, length = 7 - 5 + 1 = 8 - 4 - 1 = 3,所以length = rr - ll + 1 = r - l - 1

#include

#include

#include

#include

#include

using namespace std;

const

int maxn =

1e5+10;

#define ll long long

int n;

ll l[maxn]

,r[maxn]

;struct node

a[maxn]

;stack s;

//單調棧

void

clear

(stack

&s)int

main()

//初始化

clear

(s);

ll ans =0;

//單調棧正向遍歷找每個頂點向右的第乙個小於當前高度的點

for(

int i =

0; i < n; i++

) s.

push

(a[i]);

}//末端處理,右端點為n

while

(s.size()

>0)

//單調棧反向遍歷找每個頂點向左的第乙個小於當前高度的點

for(

int i = n-

1; i >-1

; i--

) s.

push

(a[i]);

}//末端處理,左端點為-1

while

(s.size()

>0)

//長度= (r-1) - (l+1) + 1 = r - l - 1

for(

int i =

0; i < n; i++)

cout << ans << endl;

}return0;

}/*7 2 1 4 5 1 3 3

4 1000 1000 1000 1000

0*/

Week5 A 最大矩形

week5 a 最大矩形 給乙個直方圖,求直方圖中的最大矩形的面積。例如,下面這個中直方圖的高度從左到右分別是2,1,4,5,1,3,3,他們的寬都是1,其中最大的矩形是陰影部分。input 輸入包含多組資料。每組資料用乙個整數n來表示直方圖中小矩形的個數,你可以假定1 n 100000.然後接下來...

作業記錄 WEEK5

triplet計算細節 訓練過程中的呼叫 import torch from torch.autograd import function from torch.nn.modules.distance import pairwisedistance class tripletloss functio...

作業系統學習 WEEK1 WEEK5

fork 通過複製呼叫程序來建立新的程序 exec 通過用一段新的程式 覆蓋原來的位址空間,實現程序執行 的轉換 程序的撤銷 unix exit windows terminateprocess 程序阻塞 unix wait windows waitforsingleobject 執行緒是程序中的乙...