cs的媽媽買回來好多好多很長的紙條,這些紙條的寬度都是1,長度不一樣。淘氣的cs把這些紙條剪了好多刀變得亂七八糟。ios
cs看到這麼多長長短短的紙條實在是無聊,因而把這些紙條全都擺了起來,變成下圖:web
擺成的紙條如左圖,如今cs想知道其中最大的矩形是什麼(如右圖陰影部分),請你告訴她這其中最大的矩形面積是多少。算法
第一行,一個整數N,表示有N個紙條。 第二行,N個用空格隔開的整數h1,h2,⋯,hn,表示每一個紙條的長度學習
一行,最大矩形的面積大小spa
7 2 1 4 5 1 3 3
8
4 1000 1000 1000 1000
4000
20%的數據,N≤100code
40%的數據,N≤1000orm
100%的數據,N≤100,000,0<hi<1,000,000,000ip
Time limit: 1000ms, memory limit: 65536kb.ci
=====題解正文=== it
題目解讀:
這道題目比較簡單,用普通的作法來回掃兩遍計算一下就能過,不事後來了解到有o(n)的寫法因而學習了一下試着把這個方法些粗來。
題目的數據用long long 就能過,不用寫高精度。
當咱們掃到某個柱子時只要保證當前維持着最大矩形,面對下一個柱子再進行更新就行了。
解題方法:
咱們考慮一個單調遞增的柱狀圖,那麼很顯然,最大矩形的面積能夠經過一遍掃描算出來。
咱們利用這個特性,時刻維護一個單調遞增的柱狀圖,只要維護這一個過程的時間複雜度不高總算法的時間複雜度就是o(n)
這個算法巧妙地運用了【棧】這一思想,維持棧頂的是最高的柱子。即遇到柱子i就判斷長度是否大於棧頂,若是比棧頂大就加入棧,不然就push直到棧頂不大於當前柱子的高度,而後進入棧。
在這一過程當中咱們須要計算出當前的最大值。
代碼
#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; }