SJTU OJ 2105 最大矩形

2105. 最大矩形

Description

cs的媽媽買回來好多好多很長的紙條,這些紙條的寬度都是1,長度不一樣。淘氣的cs把這些紙條剪了好多刀變得亂七八糟。ios

cs看到這麼多長長短短的紙條實在是無聊,因而把這些紙條全都擺了起來,變成下圖:web

最大矩形

擺成的紙條如左圖,如今cs想知道其中最大的矩形是什麼(如右圖陰影部分),請你告訴她這其中最大的矩形面積是多少。算法

Input Format

第一行,一個整數N,表示有N個紙條。 第二行,N個用空格隔開的整數h1,h2,,hn,表示每一個紙條的長度學習

Output Format

一行,最大矩形的面積大小spa

Sample Input

7
2
1
4
5
1
3
3

Sample Output

8

Sample Input

4
1000
1000
1000
1000

Sample Output

4000

About Testdata

20%的數據,N100code

40%的數據,N1000orm

100%的數據,N100,000,0<hi<1,000,000,000ip

Limits

Time limit: 1000ms, memory limit: 65536kb.ci




=====題解正文===  it

  1. 題目解讀:

    1. 這道題目比較簡單,用普通的作法來回掃兩遍計算一下就能過,不事後來了解到有o(n)的寫法因而學習了一下試着把這個方法些粗來。

    2. 題目的數據用long long 就能過,不用寫高精度。

    3. 當咱們掃到某個柱子時只要保證當前維持着最大矩形,面對下一個柱子再進行更新就行了。

  2. 解題方法:

    1. 咱們考慮一個單調遞增的柱狀圖,那麼很顯然,最大矩形的面積能夠經過一遍掃描算出來。

    2. 咱們利用這個特性,時刻維護一個單調遞增的柱狀圖,只要維護這一個過程的時間複雜度不高總算法的時間複雜度就是o(n)

    3. 這個算法巧妙地運用了【棧】這一思想,維持棧頂的是最高的柱子。即遇到柱子i就判斷長度是否大於棧頂,若是比棧頂大就加入棧,不然就push直到棧頂不大於當前柱子的高度,而後進入棧。

    4. 在這一過程當中咱們須要計算出當前的最大值。

  3. 代碼

    1. #include <iostream>
      #include <stack>
      using namespace std;
       
      long long n, rect[1000005];
      stack<int> s;
      long long area(0);
      int main()
      {
      	cin >> n;
      	for (int i = 0; i < n; ++i)
      		cin >> rect[i];
      	rect[n] = 0;//在最後添加一個0,爲了後期閉合這個棧。
      	for (int i = 0; i <= n; ++i)
      	{
      		if (s.empty() || rect[s.top()] < rect[i])s.push(i);
      		else
      		{//計算最大值
      			int tmp = s.top();
      			s.pop();//彈出
      			long long temp = rect[tmp] * (s.empty() ? i : i - s.top() - 1);
      			if (area < temp)area = temp;
      			--i;
      		}
      	}
      	cout << area;
      }
相關文章
相關標籤/搜索