第五周 A 最大矩形

2021-10-04 10:36:09 字數 1943 閱讀 2434

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

input

輸入包含多組資料。每組資料用乙個整數n來表示直方圖中小矩形的個數,你可以假定1 <= n <= 100000. 然後接下來n個整數h1, …, hn, 滿足 0 <= hi <= 1000000000. 這些數字表示直方圖中從左到右每個小矩形的高度,每個小矩形的寬度為1。 測試資料以0結尾。

output

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

sample input

7 2 1 4 5 1 3 3

4 1000 1000 1000 1000

0sample output

84000

將h1, …, hn存入陣列h[100001]。要求最大矩形面積,需要對每乙個h[i]求出以h[i]為高度的矩形的面積。h[i]高度已知,需要求出矩形的寬度,則需求出矩形的左邊界l和右邊界r的位置,即可通過公式寬度=r-l-1計算出寬度。對於h[i],左邊界為h中左邊數第乙個高度小於h[i]的元素下標+1,右邊界為h中右邊數第乙個高度小於h[i]的元素下標-1。面積s=h[i]*(r-l+1)。

對每乙個h[i],分別往左,往右迭代找出左右邊界,則時間複雜度為n²,會超時。

本題使用非增棧資料結構,只需要遍歷陣列h一次就可以找到每個h[i]的左/右邊界。設棧為st,棧儲存的資料型別為h[i]的下標i。記錄h[i]的左邊界為l[i],右邊界為r[i]。

右邊界的尋找方法:遍歷h,從左到右依次對單調棧st進行push(i)操作,若h[i]小於棧頂元素,則彈出棧頂元素,此時,i便為棧頂元素往右數第乙個小於棧頂元素的元素的下標。則棧頂元素st.top()的右邊界為i-1,將這個資訊記錄為r[st.top()]=i-1。就這樣push(i)到末尾,完成迭代後,若st內還存在元素,則這些元素的右邊界為陣列的末尾,即n,因此要把棧內剩餘元素全部彈出,並記錄下來r[st.top()]=n。此時遍歷完成,h內所有元素均入棧一次,出棧一次,並且其右邊界的下標被儲存在r中。左邊界與右邊界思路一致,只是掉轉了遍歷的方向。使用上述方法,複雜度為n。

注意高度h的取值範圍,需要使用long long int 來儲存高度和面積,否則會出錯。

#include

#include

using

namespace std;

long

long

int h[

100010

],ans,s;

int n,l[

100001

],r[

100001];

inline

long

long

intmax

(long

long

int a,

long

long

int b)

stack<

int> st;

intmain()

for(

int i=

1;i<=n;i++

) st.

push

(i);

}while

(!st.

empty()

)for

(int i=n;i>=

1;i--

) st.

push

(i);

}while

(!st.

empty()

)for

(int i=

1;i<=n;i++

)printf

("%lld\n"

,ans);}

return0;

}

第五周周總結

時間進度表 日期開始時間 結束時間 中斷時間 淨時活動 備註3月15日 7 10 9 10 120打程式 規範 進行初步構思 3月16日 7 10 9 10 120打程式 實現減法無負數 3月17日 8 00 10 00 120打程式 實現減法無負數 3月18日 4 10 5 50 5 00 5 1...

第五周周記

第五周周記 本週完成了 1.html的網頁設計作業,學習了標籤 用 製作網頁 製作表單站點等。2.學習了資料結構的順序表和鏈式表的動態儲存和應用,以及如何寫 3.學習了ps 選單的部分功能。4.學會了繪製一張網路拓撲圖。希望能夠更加努力,收穫成長。週數專業學習目標 專業學習時間 新增 量 部落格發表...

第五周作業

includeusing namespace std class student 用引數的初始化表對資料成員初始化。void max student arr void display private int num int score void student display void studen...