E - 秋实大哥去打工
Time Limit:1000MS Memory Limit:65535KB 64bit IO Format:%lld & %llu
Submit Status Practice UESTC 1069
Appoint description:
System Crawler (2016-04-24)
Description
天行健,君子以自强不息。地势坤,君子以厚德载物。
天天过节的秋实大哥又要过节了,于是他要给心爱的妹子买礼物。但由于最近秋实大哥手头拮据,身为一个男人,他决定去打工!
秋实大哥来到一家广告公司。现在有n块矩形墙从左至右紧密排列,每一块高为Hi,宽为Wi。
公司要求秋实大哥找出一块最大的连续矩形区域,使得公司可以在上面贴出最大的海报。
Input
第一行包含一个整数n,表示矩形墙的个数。
接下来n行,每行有两个整数Wi,Hi,表示第i块墙的宽度和高度。
1≤n≤200000,保证Wi,Hi以及最后的答案<231。
Output
最大的连续矩形的面积。
Sample Input
3
3 4
1 2
3 4
Sample Output
14
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include <queue> #include <stack> #include <map> #include <algorithm> #include <set> using namespace std; typedef long long LL; typedef unsigned long long Ull; #define MM(a,b) memset(a,b,sizeof(a)); const double eps = 1e-10; const int inf = 0x3f3f3f3f; const double pi=acos(-1); const int maxn=200000; int w[maxn+10],h[maxn+10]; int l[maxn+10],r[maxn+10],x[maxn+10]; int main() { int n; while(~scanf("%d",&n)) { MM(l,0);MM(r,0);MM(x,0); for(int i=1;i<=n;i++) scanf("%d %d",&w[i],&h[i]); x[1]=1; for(int i=2;i<=n+1;i++) x[i]=x[i-1]+w[i-1];//处理每个点的坐标 stack<int> stl; for(int i=1;i<=n;i++) { while(stl.size()&&h[stl.top()]>=h[i]) stl.pop(); l[i]=stl.size()==0?1:stl.top()+1; stl.push(i); } stack<int> str; for(int i=n;i>=1;i--) { while(str.size()&&h[i]<=h[str.top()]) str.pop(); r[i]=str.size()==0?n+1:str.top(); str.push(i); } int maxn=0; for(int i=1;i<=n;i++) maxn=max(maxn,(x[r[i]]-x[l[i]])*h[i]); printf("%d\n",maxn); } return 0; }
分析:裸的单调栈,需要处理好每个点的下标就好
时间: 2024-10-12 07:19:46