Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 24316 | Accepted: 7866 |
Description
Usually, histograms are used to represent discrete distributions, e.g., the frequencies of characters in texts. Note that the order of the rectangles, i.e., their heights, is important. Calculate the area of the largest rectangle in a histogram that is aligned at the common base line, too. The figure on the right shows the largest aligned rectangle for the depicted histogram.
Input
Output
Sample Input
7 2 1 4 5 1 3 3 4 1000 1000 1000 1000 0
Sample Output
8 4000
Hint
Source
单调栈计算每个矩形往左、往右所能够达到的最远距离。(入栈判断左边界,出栈判断右边界)
PS:我用的是左开右闭区间。
一个小技巧:栈中直接维护位置信息,这样就不用开两个栈或是结构体了。
2.解题思路
1 #include<iostream> 2 #include<stack> 3 #include<algorithm> 4 #include<string> 5 #include<cstring> 6 #include<cstdio> 7 using namespace std; 8 int h[100005]; 9 int l[100005]; 10 int r[100005]; 11 stack<int>s; 12 long long max1(long long a,long long b) 13 { 14 15 if(a>=b) return a; 16 else return b; 17 } 18 int main() 19 { 20 int n; 21 while(~scanf("%d",&n)) 22 { 23 if(n==0) break; 24 for(int i=1;i<=n;i++) 25 scanf("%lld",&h[i]); 26 27 while(!s.empty()) s.pop(); 28 for(int i=1;i<=n;i++) 29 { 30 while(!s.empty()&&h[s.top()]>=h[i]) s.pop();//向左找找到比它矮的就跳出 31 if(s.empty()) l[i]=1;//如果此时之前没东西,那就是从1开始 32 else l[i]=s.top()+1;//否则就是它前面的一个 33 s.push(i); 34 } 35 36 while(!s.empty()) s.pop(); 37 for(int i=n;i>=1;i--) 38 { 39 while(!s.empty()&&h[s.top()]>=h[i]) s.pop();//向右找找到比它矮的就跳出 40 if(s.empty()) r[i]=n;//如果此时之前没东西,那就是可以一直到最右端 41 else r[i]=s.top()-1;//否则就是它前面的一个 42 s.push(i); 43 } 44 45 long long s=0; 46 for(int i=1;i<=n;i++) 47 { 48 s=max1(s,(long long)h[i]*(r[i]-l[i]+1));//以i为中心,找到了左右就可以求面积了 49 } 50 51 printf("%lld\n",s); 52 } 53 return 0; 54 }
用数组模拟
1 #include<iostream> 2 #include<stack> 3 #include<algorithm> 4 #include<string> 5 #include<cstring> 6 #include<cstdio> 7 using namespace std; 8 int h[100005]; 9 int l[100005]; 10 int r[100005]; 11 int st[100005]; 12 long long max1(long long a,long long b) 13 { 14 15 if(a>=b) return a; 16 else return b; 17 } 18 int main() 19 { 20 int n; 21 while(~scanf("%d",&n)) 22 { 23 if(n==0) break; 24 memset(st,0,sizeof(st)); 25 for(int i=0;i<n;i++) scanf("%d",&h[i]); 26 27 int t=0; 28 for(int i=0;i<n;i++) 29 { 30 while(t>0&&h[st[t-1]]>=h[i]) t--; 31 l[i]=(t==0?0:(st[t-1]+1)); 32 st[t++]=i; 33 } 34 35 t=0; 36 for(int i=n-1;i>=0;i--) 37 { 38 39 while(t>0&&h[st[t-1]]>=h[i]) t--; 40 r[i]=(t==0?n:st[t-1]); 41 st[t++]=i; 42 } 43 long long s=0; 44 for(int i=0; i<n; i++) 45 { 46 s=max1(s,(long long)h[i]*(r[i]-l[i]));//以i为中心,找到了左右就可以求面积了 47 } 48 49 printf("%lld\n",s); 50 } 51 return 0; 52 }
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 24316 | Accepted: 7866 |
Description
Usually, histograms are used to represent discrete distributions, e.g., the frequencies of characters in texts. Note that the order of the rectangles, i.e., their heights, is important. Calculate the area of the largest rectangle in a histogram that is aligned at the common base line, too. The figure on the right shows the largest aligned rectangle for the depicted histogram.
Input
Output
Sample Input
7 2 1 4 5 1 3 3 4 1000 1000 1000 1000 0
Sample Output
8 4000
Hint
Source
单调栈计算每个矩形往左、往右所能够达到的最远距离。(入栈判断左边界,出栈判断右边界)
PS:我用的是左开右闭区间。
一个小技巧:栈中直接维护位置信息,这样就不用开两个栈或是结构体了。
2.解题思路
1 #include<iostream> 2 #include<stack> 3 #include<algorithm> 4 #include<string> 5 #include<cstring> 6 #include<cstdio> 7 using namespace std; 8 int h[100005]; 9 int l[100005]; 10 int r[100005]; 11 stack<int>s; 12 long long max1(long long a,long long b) 13 { 14 15 if(a>=b) return a; 16 else return b; 17 } 18 int main() 19 { 20 int n; 21 while(~scanf("%d",&n)) 22 { 23 if(n==0) break; 24 for(int i=1;i<=n;i++) 25 scanf("%lld",&h[i]); 26 27 while(!s.empty()) s.pop(); 28 for(int i=1;i<=n;i++) 29 { 30 while(!s.empty()&&h[s.top()]>=h[i]) s.pop();//向左找找到比它矮的就跳出 31 if(s.empty()) l[i]=1;//如果此时之前没东西,那就是从1开始 32 else l[i]=s.top()+1;//否则就是它前面的一个 33 s.push(i); 34 } 35 36 while(!s.empty()) s.pop(); 37 for(int i=n;i>=1;i--) 38 { 39 while(!s.empty()&&h[s.top()]>=h[i]) s.pop();//向右找找到比它矮的就跳出 40 if(s.empty()) r[i]=n;//如果此时之前没东西,那就是可以一直到最右端 41 else r[i]=s.top()-1;//否则就是它前面的一个 42 s.push(i); 43 } 44 45 long long s=0; 46 for(int i=1;i<=n;i++) 47 { 48 s=max1(s,(long long)h[i]*(r[i]-l[i]+1));//以i为中心,找到了左右就可以求面积了 49 } 50 51 printf("%lld\n",s); 52 } 53 return 0; 54 }
用数组模拟
1 #include<iostream> 2 #include<stack> 3 #include<algorithm> 4 #include<string> 5 #include<cstring> 6 #include<cstdio> 7 using namespace std; 8 int h[100005]; 9 int l[100005]; 10 int r[100005]; 11 int st[100005]; 12 long long max1(long long a,long long b) 13 { 14 15 if(a>=b) return a; 16 else return b; 17 } 18 int main() 19 { 20 int n; 21 while(~scanf("%d",&n)) 22 { 23 if(n==0) break; 24 memset(st,0,sizeof(st)); 25 for(int i=0;i<n;i++) scanf("%d",&h[i]); 26 27 int t=0; 28 for(int i=0;i<n;i++) 29 { 30 while(t>0&&h[st[t-1]]>=h[i]) t--; 31 l[i]=(t==0?0:(st[t-1]+1)); 32 st[t++]=i; 33 } 34 35 t=0; 36 for(int i=n-1;i>=0;i--) 37 { 38 39 while(t>0&&h[st[t-1]]>=h[i]) t--; 40 r[i]=(t==0?n:st[t-1]); 41 st[t++]=i; 42 } 43 long long s=0; 44 for(int i=0; i<n; i++) 45 { 46 s=max1(s,(long long)h[i]*(r[i]-l[i]));//以i为中心,找到了左右就可以求面积了 47 } 48 49 printf("%lld\n",s); 50 } 51 return 0; 52 }