8 条题解

  • 2
    @ 2022-1-19 16:08:02

    C++:

    #include

    #include

    #include

    using namespace std;

    int q[100001];

    int a[100001];

    int n,t;

    int ll;

    //int h[100001];

    int l[100001];

    int r[100001];

    void make(int an[100001])

    { //int l=1;

    ll=0;
    
    a[0]=-1;
    
    for(int i=1;i<=n;i++)
    
    {
    
    	while(a[q[ll]]>=a[i])
    
    	{
    
    		ll--;
    
    	}
    
    	an[i]=q[ll];
    
    	q[++ll]=i;
    
    }
    

    }

    long long maxn;

    int main()

    {

    while(scanf("%d",&n))
    
    {
    
    	if(n==0)
    
    	{
    
    		return 0;
    
    	}
    
    	for(int i=1;i<=n;i++)
    
    	{
    
    		scanf("%d",&a[i]);
    
    	}
    
    	a[0]=-1;
    
    	make(l);
    
    	reverse(a+1,a+1+n);
    
    	make(r);
    
    	//int j=n;
    
    	maxn=0;
    
    	for(int i=1,j=n;i<=n;i++,j--)
    
    	{
    
    		maxn=max(maxn,a[i]*(n-l[j]-r[i]+1-(long long)(1)));
    
    	//	j--;
    
    	}
    
    	printf("%lld\n",maxn);
    
    }
    

    }

    • 1
      @ 2024-1-27 11:46:22

      因为对于一个高度 hih_i, 我们往左边一直以这个高度延伸,直到不行,再往右边进行一样的操作

      那么什么时候不行呢,就是当想要继续延伸的块高度比hih_i

      左边的极限就是 hl  (hl1<hi)h_l \ \ (h_{l-1}<h_i) 右边的极限就是 hr  (hr+1<hi)h_r \ \ (h_{r+1}<h_i)

      那么以 ii 为原点往左右两边延伸的最大面积就是(rl+1)hi(r-l+1)*h_i

      我们使用单调栈即可求出 l1l-1r+1r+1,我们暂时记为 ans1ans1ans2ans2

      那么上述提到的面积就是(ans2ans11)hi(ans2-ans1-1)*h_i 自己推导一下就知道了


      AC CODE

      #include <bits/stdc++.h> 
      using namespace std;
      const long long N = 1e5+10,INF = 0x3f3f3f3f;
      long long a[N],ans[N],ans2[N],st[N],n,top,res,tmp;
      void calc1(){
      	for(long long i = 1; i <= n; i++){
      		while(top>0&&a[i]<=a[st[top]])top--;
      		ans[i]=st[top];st[++top]=i;
      	}//单调栈模版,但是>=改成<=以达到效果 
      }
      void calc2(){
      	for(long long i = n; i >= 1; i--){
      		while(top>0&&a[i]<=a[st[top]])top--;
      		ans2[i]=st[top];st[++top]=i;
      	}//单调栈模版,但是>=改成<=以达到效果 
      }
      void solve(){
      	cin >> n;
      	if(n==0)exit(0);
      	top = 0, res = 0, a[0]=a[n+1]=-INF;
      	for(long long i = 1; i <= n; i++)cin >> a[i];
      	top = 0;st[++top]=0;calc1();//计算ans1 
      	top = 0;st[++top]=n+1;calc2();//计算ans2 
      	for(long long i = 1; i <= n; i++)res = max(res,(ans2[i]-ans[i]-1)*a[i]);
      	cout << res << '\n';
      }
      signed main(){
      	while(1+1==2)solve();
      	return 0;
      }//完美30行结束 
      
      • 1
        @ 2022-2-10 15:36:15

        c++

        //
        #include<iostream>
        #include<cmath>
        #include<algorithm>
        #include<cstdio>
        using namespace std;
        typedef long long LL;
        const int MAXN = 1e6 + 10;
        const int INF = 0x3f;
        LL n, a[MAXN];
        LL stack[MAXN];
        LL l[MAXN], r[MAXN], top = 0;
        int main()
        {
        	start:cin >> n;
        	if(n == 0)return 0;
        	for (int i = 0;i < n; i++)
        	{
        		cin >> a[i];
        	}
        	top = 0;
        	a[0] = -1;
        	for(int i = 1;i <= n; i++)
        	{
        		while(top >= 0 && a[i] <= a[ stack[top - 1] ])
        			top--;
        		l[i] = top == 0 ? 0 : (stack[top - 1] + 1);
        		stack[top++] = i;
        	}
        	top = 0;
        	a[0] = -1;
        	for(int i = n - 1;i >= 0; i--)
        	{
        		while(top > 0 && a[i] <= a[ stack[top - 1] ])
        			top--;
        		r[i] = top == 0 ? 0 : (stack[top - 1]);
        		stack[top++] = i;
        	}
        	LL ans = 0;
        	for(int i = 1;i <= n;i++){
        		//cout << l[i] << ' ' << r[i] << ' ' << a[i] << endl;
        		ans = max(ans, (r[i] - l[i]) * a[i]);
        	}
        	cout << ans << endl;
        	goto start;
        }
        
        • 1
          @ 2021-8-7 19:00:39

          C++ :

          #include<iostream>
          #include<algorithm>
          #include<vector>
          #include<stack>
          
          using namespace std;
          typedef long long ll;
          const int N = 1e5 + 5;
          
          int n;
          int h[N], q[N], l[N], r[N];
          
          void get(int bound[N])
          {
              int tt = 0;
              h[0] = -1;
              for(int i = 1; i <= n; i ++ ){
                  while(h[q[tt]] >= h[i]) tt -- ;
                  bound[i] = q[tt];
                  q[ ++ tt] = i;
              }
          }
          
          int main()
          {
              while(cin >> n, n){
                  for(int i = 1; i <= n; i ++ )
                      cin >> h[i];
                  //立一个标兵在队头
                  h[0] = -1;
                  get(l);
                  reverse(h + 1, h + n + 1);
                  get(r);
          
                  ll res = 0;
                  //因为之前翻转了一下,所有原本的下标变成了对称位置的下标,1ll是long long 形式的1
                  for(int i = 1, j = n; i <= n; i ++, j -- )
                      res = max(res, h[i] * (n + 1 - l[j] - r[i] - 1ll));
                  cout << res << endl;
              }
              return 0;
          }
          
          • 0
            @ 2025-4-6 19:53:06

            // #include #include #include #include using namespace std; typedef long long LL; const int MAXN = 1e6 + 10; const int INF = 0x3f; LL n, a[MAXN]; LL stack[MAXN]; LL l[MAXN], r[MAXN], top = 0; int main() { start: cin >> n; if(n == 0)return 0; for (int i = 0; i < n; i++) { cin >> a[i]; } top = 0; a[0] = -1; for(int i = 1; i <= n; i++) { while(top >= 0 && a[i] <= a[ stack[top - 1] ]) top--; l[i] = top == 0 ? 0 : (stack[top - 1] + 1); stack[top++] = i; } top = 0; a[0] = -1; for(int i = n - 1; i >= 0; i--) { while(top > 0 && a[i] <= a[ stack[top - 1] ]) top--; r[i] = top == 0 ? 0 : (stack[top - 1]); stack[top++] = i; } LL ans = 0; for(int i = 1; i <= n; i++) { //cout << l[i] << ' ' << r[i] << ' ' << a[i] << endl; ans = max(ans, (r[i] - l[i]) * a[i]); } cout << ans << endl; goto start; }

            • 0
              @ 2023-5-26 17:23:36

              思路:

              我们找到左边第一个比他小和右边第一个比它小的,就可以得知这个高度的矩形的宽**
              

              代码:

              #include<iostream>
              #include<stack>
              #define int long long
              using namespace std;
              stack<int> st;
              int h[100005],n,to,l[100005],r[100005],ans;
              signed main(){
                  while(cin>>n,n){
                      for(int i=1;i<=n;i++) cin>>h[i];
                      h[0]=-1;
                      st.push(0);
                      for(int i=1;i<=n;i++){
                          while(!st.empty()&&h[i]<=h[st.top()]) st.pop();
                          l[i]=st.top();
                          st.push(i);
                      }
                      while(!st.empty()) st.pop();
                      h[n+1]=-1;
                      st.push(n+1);
                      for(int i=n;i>=1;i--){
                          while(!st.empty()&&h[i]<=h[st.top()]) st.pop();
                          r[i]=st.top();
                          st.push(i);
                      }
                      ans=0;
                      for(int i=1;i<=n;i++){
                          ans=max(ans,(r[i]-l[i]-1)*h[i]);
                      }
                      cout<<ans<<endl;
                  }
                  return 0;
              }
              
              
              
              • -3
                @ 2022-2-9 20:09:03

                #include<cstdio> #include<stack> #include<iostream> #include<algorithm> using namespace std; int n,h[100000],ans=0,x; stack<int>st; bool va(int xx){ if(st.empty()){ return false; } else return st.top()>h[xx]; } int main(){ while(cin>>n &&n){ for(int i=1;i<=n;i++){ scanf("%d",&h[i]); } h[n+1]=-1; st.push(h[1]); for(int i=2;i<=n+1;i++){ x=0; while(va(i)){ x++; ans=max(x*st.top(),ans); st.pop(); } st.push(h[i]); } printf("%d\n",ans);} }

                本体思路太蒟蒻

                • -4
                  @ 2022-1-19 15:24:47

                  #include<stdio.h> #include<string.h> #include using namespace std; typedef long long ll; const int N = 1e5 + 5; ll l[N], r[N]; ll a[N]; int n; stack s; int main(){ while(scanf("%d",&n) && n){ while(!s.empty()) s.pop(); for(int i=1; i<=n; ++i){ scanf("%lld",&a[i]); l[i] = r[i] = i; } a[0] = a[n+1] = -1;

                  	for(int i=1; i<=n; ++i){
                  		while(!s.empty() && a[i] <= a[s.top()])
                  	    s.pop();
                  	    if(s.empty()) l[i] = 0;
                  	    else  l[i] = s.top();
                  	    s.push(i);
                  	}
                  	
                  	while(!s.empty())  s.pop();
                  
                  	for(int i=n; i>=1; --i){
                  		while(!s.empty() && a[i] <= a[s.top()])
                  	    s.pop();
                  	    if(s.empty())  r[i] = n+1;
                      	else  r[i] = s.top();
                  	    s.push(i);
                  	}
                  
                  	ll sum, max = -1;
                      for(int i=1; i<=n; ++i){
                          sum = (r[i] - l[i] - 1) * a[i];
                          if(sum > max) max = sum;
                      }
                      printf("%lld\n",max);
                  }
                  return 0;
                  

                  }

                  • 1

                  信息

                  ID
                  42
                  时间
                  1000ms
                  内存
                  128MiB
                  难度
                  5
                  标签
                  递交数
                  257
                  已通过
                  97
                  上传者