zoukankan      html  css  js  c++  java
  • POJ 2559 单调栈入门,三种代码实现

    POJ 2559 单调栈入门,三种代码实现

    题意

    给你一连串的矩形的高度,他们宽的长度都是1,求组成的最大矩形的面积。

    解题思路

    其实就是求以每个数为最小值时,这个区间范围是什么?

    暴力肯定不行,因为复杂度为O(N^2),会超时,所以我们要寻找一个更加好的办法。这里单调栈就显示出来优势了。我们可以达到O(N)的复杂度来实现这个操作。

    代码实现

    下面有三种实现方式,代码都值得参考。

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<string>
    #include<stack>
    #include<queue>
    #include<map>
    typedef long long ll;
    using namespace std;
    const double esp=1e-6;
    const int inf=0x3f3f3f3f;
    const int MAXN=1E5+7;
    ll num[MAXN], st[MAXN];
    int n, top, lt[MAXN], rt[MAXN];
    int main()
    {
    	while(scanf("%d",&n) && n!=0)
    	{
    		top=1; 
    		st[top]=0;
    		num[0]=-1; num[n+1]=-1;
    		for(int i=1; i<=n; i++)
    			scanf("%lld", &num[i]);
    		for(int i=1; i<=n+1; i++)
    		{
    			lt[i]=i;//最差就是这种情况
    			rt[i]=i;
    			while(num[st[top]] > num[i])//单调不减的栈 
    			{
    				lt[i] = lt[st[top]]; //我们可以确定当前的i的最左边是栈顶元素的最左边
    				rt[st[top]] = i-1; //而栈顶元素的最右边就是i-1
    				top--;	 
    			}
    			if(num[st[top]] == num[i]) lt[i] = lt[st[top]]; //和栈顶元素相等的时候
    			st[++top]=i;
    		}
    //		for(int i=1; i<=n; i++)
    //			printf("%d %d
    ", lt[i], rt[i]);
    		ll ans=-1;
    		for(int i=1; i<=n; i++)
    		{
    			ans = max(ans, (rt[i] - lt[i] + 1)*num[i] );
    		} 
    		printf("%lld
    ", ans);
    	}
    	return 0;
    }
    
    //比较简单的实现方式
    #include <stdio.h>
    #include <iostream>
    #include <stack>
    #define X 1000010
    
    using namespace std;
    
    stack<int >s;
    int n,x;
    long long a[X],m,ans,r[X],l[X];
    int main()
    {
      //  freopen("in.txt","r",stdin);
        while(scanf("%d",&n),n!=0){
            ans=0;
            a[0]=-1;
    		a[n+1]=-1;
            for(int i=1;i<=n;i++)
                scanf("%lld",&a[i]);
            while(!s.empty())
                s.pop();  
    		
    		s.push(0);
            for(int i=1;i<=n;i++){
                for(x=s.top();a[x]>=a[i];x=s.top())
                    s.pop();
                l[i]=x+1;
                s.push(i);
            }
            while(!s.empty())
                s.pop();
                
    		s.push(n+1);
    		for(int i=n;i>0;i--){
                for(x=s.top();a[x]>=a[i];x=s.top())
                    s.pop();
                r[i]=x-1;
                s.push(i);
                if((r[i]-l[i]+1)*a[i]>ans) ans=(r[i]-l[i]+1)*a[i];
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    
    //https://blog.csdn.net/zuzhiang/article/details/78135142
    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<stack>
    using namespace std;
    
    int main()
    {
    	//top指向栈顶;tmp为临时变量,记录面积的值;ans为答案,记录面积的最大值 
    	int i,j,m,n,x,top,tmp,ans,h[2020],a[2020];
    	stack<int> st; //单调栈,记录位置 
    	while(~scanf("%d%d",&m,&n))
    	{
    		ans=0;
    		memset(h,0,sizeof(h)); //用于第一行的处理
    		for(i=0;i<m;i++)
    		{   //扫描每一行 
    			for(j=1;j<=n;j++)
    			{
    				scanf("%d",&x);
    				if(x==1) h[j]=h[j]+1; //如果是1,则在上一行本列的基础上+1 
    				else h[j]=0; //否则为0 
    				a[j]=h[j]; //a数组用来向左右扩展
    			}
    			a[n+1]=-1; //设最后元素为最小值,以最后让栈内元素出栈 
    			for(j=1;j<=n+1;j++)
    			{
    				if(st.empty()||a[j]>=a[st.top()])
    				{ //如果栈为空或入栈元素大于等于栈顶元素,则入栈 
    					st.push(j);
    				}
    				else
    				{
    					while(!st.empty()&&a[j]<a[st.top()])
    					{ //如果栈非空并且入栈元素小于栈顶元素,则将栈顶元素出栈 
    						top=st.top();
    						st.pop();
    						tmp=(j-top)*a[top]; //计算面积值 
    						if(tmp>ans) ans=tmp; //更新面积最大值 
    					}
    					st.push(top); //将最后一次出栈的栈顶元素延伸并入栈 
    					a[top]=a[j]; //修改其对应的值 
    				}
    			}
    		}
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    潜移默化学会WPF绘图 学习(一)
    MovablePlane issue
    ogre Fix bug in HLSL with 3×4 matrix arrays
    如何加强角色渲染的真实感(self shadow + subsurface scattering + rim lighting)
    The DirectX SDK (February 2010) release is now live on Microsoft downloads.
    Color Spaces
    游戏主循环
    实时动态云 perlin noise + 光照 + 太阳光遮挡
    这几个礼拜做的事情
    ogre无法读取中文路径的解决办法
  • 原文地址:https://www.cnblogs.com/alking1001/p/12293372.html
Copyright © 2011-2022 走看看