1. 程式人生 > >LC的課後輔導 棧的應用

LC的課後輔導 棧的應用

-s 測試數據 每一個 tps %d tar cti 說明 ack

LC的課後輔導

發布時間: 2015年9月19日 21:42 時間限制: 1000ms 內存限制: 256M

有一天,LC給我們出了一道題,如圖:

技術分享

這個圖形從左到右由若幹個 寬為1 高不確定 的小矩形構成,求出這個圖形所包含的最大矩形面積。

多組測試數據 每組測試數據的第一行為n(0 <= n <= 100), 表示圖形有n個小矩形構成 接下來一行輸入n個整數h1, h2...hn(0 <= hi <= 1000), 表示每個小矩形的高度 n為0時程序結束

僅輸出一行表示面積的最大值

復制
7
2 1 4 5 1 3 3
4
1000 1000 1000 1000
0
8

4000

思路:開兩個數組分別記錄每一個矩形以他為中心所能達到的左右長度,然後面積就是h*(r-l+1);這裏要註意的是如果該矩形比上一個或後一個矩形要小,則上一個矩形所能達到的區間,該矩形一定可以達到,
ac代碼:
#include<stdio.h>
int main()
{   int a[101];
    int n,max,i;
    while(scanf("%d",&n)!=EOF)
    {   
      if(n==0)
        break;
    for(i=1;i<=n;i++)
       scanf("%d
",&a[i]); int l[101],r[101]; l[1]=1; r[n]=n; int t; for(i=2;i<=n;i++) { t=i; while(t>1&&a[i]<=a[t-1]) t=l[t-1]; l[i]=t; } for(i=n-1;i>=1;i--) { t=i; while(t<n&&a[i]<=a[t+1]) t=r[t+1]; r[i]
=t; } int max=-1; for(i=1;i<=n;i++) { if((r[i]-l[i]+1)*a[i]>max) max=(r[i]-l[i]+1)*a[i]; } printf("%d\n",max);} return 0; } 最近在接觸單調棧,又用棧實現了一下,這裏維護一個單增棧,那麽如果要進棧的數不能直接入棧,說明當前棧頂比他大,就說明它可以延伸,一直到可以進棧為止,也就是說通過維護單增棧我們一定可以找到左面第一個比他小的和右面第一個比他小的; 還有這裏因為矩形的高度可能相同,所以當棧為空時說明可以延伸到頭或者尾; #include<stdio.h> #include<string.h> #include<algorithm> #include<stack> #define N 100010 using namespace std; int a[N],l[N],r[N]; int main() { int n,i; while(scanf("%d",&n)!=EOF){ if(n==0) break; stack<long long >st; while(!st.empty()) st.pop(); l[1]=1; st.push(1); for(i=1;i<=n;i++) scanf("%d",&a[i]); for(i=1;i<=n;i++) { if(a[st.top()]>=a[i]) { while(!st.empty()&&a[st.top()]>=a[i]) { st.pop(); } if(st.empty()) l[i]=1; else l[i]=st.top()+1; st.push(i); } else { l[i]=i; st.push(i); } } while(!st.empty()) st.pop(); r[n]=n; st.push(n); for(i=n;i>=1;i--) { if(a[st.top()]>=a[i]) { while(!st.empty()&&a[st.top()]>=a[i]) { st.pop(); } if(st.empty()) r[i]=n; else r[i]=st.top()-1; st.push(i); } else { r[i]=i; st.push(i); } } //for(i=1;i<=n;i++) //printf("%d %d\n",l[i],r[i]); long long ans=0; for(i=1;i<=n;i++) ans=max(ans,(long long)(r[i]-l[i]+1)*a[i]); printf("%lld\n",ans); } return 0; }

LC的課後輔導 棧的應用