• 【CCF 201312-3】最大的矩形(单调栈) & 【POJ 2823】Sliding Window(单调队列) Apare_xzc


    最大的矩形(单调栈) & Sliding Window(单调队列)


    今天刷CCF的时候碰到了最大的矩形这个题,顺便复习了一下单调栈和单调队列

    Sliding Window

    POJ 2823题目链接<–

    题意:

       给一个1E6长的数列,求每个长度为K的区间的最大值和最小值
    在这里插入图片描述

    代码:

    /*
    POJ 2823 Sliding Window
    Run ID	    User	Problem	 Result	    Memory	Time	Language	Code Length	 Submit Time
    21072853	apare	2823	 Accepted	4016K	5516MS	C++	        1249B	     2019-11-20 14:03:59
    21072236	apare	2823	 Time Limit Exceeded		C++	823B	             2019-11-20 11:26:56
    单调队列,用deque TLE了,用数组模拟队列,5516MS过了 
    */
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    //#include <deque>
    using namespace std;
    const int maxn = 1e6+100;
    int a[maxn];
    int Q[maxn];
    int main()
    {
    	int n,k;
    	scanf("%d%d",&n,&k);
    	for(int i=1;i<=n;++i)
    	{
    		scanf("%d",a+i);	
    	}
    /*	
    	deque<pair<int,int> >Q; //pair<value,pos>
    	for(int i=1;i<=n;++i)
    	{  
    		while(!Q.empty()&&a[i]<=Q.back().first) Q.pop_back();
    		Q.push_back(make_pair(a[i],i));
    		while(!Q.empty()&&Q.front().second<=Q.back().second-k) Q.pop_front();
    		if(i>=k) printf("%d%c",Q.front().first,i==n?'
    ':' ');	
    	}
    	Q.clear();
    	for(int i=1;i<=n;++i)
    	{  
    		while(!Q.empty()&&a[i]>=Q.back().first) Q.pop_back();
    		Q.push_back(make_pair(a[i],i));
    		while(!Q.empty()&&Q.front().second<=Q.back().second-k) Q.pop_front();
    		if(i>=k) printf("%d%c",Q.front().first,i==n?'
    ':' ');	
    	}
    	return 0;
    */
    	int pf = 0,pb = 0;
    	for(int i=1;i<=n;++i)
    	{
    		while(pb>pf&&a[i]<=a[Q[pb-1]]) pb--;
    		Q[pb++] = i;
    		while(pb>pf&&Q[pf]<=Q[pb-1]-k) pf++;
    		if(i>=k) printf("%d%c",a[Q[pf]],i==n?'
    ':' ');
    	} 
    	pf = pb = 0;
    	for(int i=1;i<=n;++i)
    	{
    		while(pb>pf&&a[i]>=a[Q[pb-1]]) pb--;
    		Q[pb++] = i;
    		while(pb>pf&&Q[pf]<=Q[pb-1]-k) pf++;
    		if(i>=k) printf("%d%c",a[Q[pf]],i==n?'
    ':' ');
    	} 
    	return 0;	
    } 
    

    最大的矩形

    题意:求最大的矩形的面积

    在这里插入图片描述
    在这里插入图片描述

    思路:

    • 求最大的矩形的面积,那么求高度为h[1],h[2],h[3]…到h[n]的最大的矩形面积的最大值
    • 那么我们要做的就是处理出每个高度h[i]左边和右边能拓展的长度(找到左右两边最远的高度>=h[i]的坐标L[i]和R[i])
    • 那么ans = max(ans, h[i]*(R[i]-L[i]+1))
    • 可以用单调栈维护:
      先把0入栈,然后从做到右和从右到左分别维护单调递增的栈
    pos         0 1 2 3 4 5 6 
    height      0 3 1 6 5 2 4  
         0
         0 3(0个)
         0 1(1个) 
         0 1 6
         0 1 5
         0 1 2
         0 1 2 4
    

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int a[1005],L[1005],R[1005];
    int main()
    {
    	int n;
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i)
    		scanf("%d",a+i);
    	stack<pair<int,int> > st; //pair(value,pos)
    	st.push(make_pair(0,0));
    	for(int i=1;i<=n;++i)
    	{
    		while(!st.empty()&&st.top().first>=a[i]) st.pop();
    		L[i] = st.top().second+1; 
    		st.push(make_pair(a[i],i));
    	}
    	while(!st.empty()) st.pop();
    	st.push(make_pair(0,n+1));
    	for(int i=n;i>=1;--i)
    	{
    		while(!st.empty()&&st.top().first>=a[i]) st.pop();
    		R[i] = st.top().second-1;
    		st.push(make_pair(a[i],i));
    	}
    	int ans = 0;
    	for(int i=1;i<=n;++i)
    		ans = max(ans,a[i]*(R[i]-L[i]+1));
    	printf("%d
    ",ans);
    	
    	return 0;
    }
    

  • 相关阅读:
    使用auto_prepend_file和auto_append_file
    maven导入外部jar包的方法
    scala的多种集合的使用(3)之遍历集合的方法
    scala的多种集合的使用(4)之列表List(ListBuffer)的操作
    scala的多种集合的使用(2)之集合常用方法
    UltraEdit文本行数多变一和一边多
    scala的多种集合的使用(1)之集合层级结构与分类
    用Case类生成模板代码
    寻:IE总弹出广告窗口方法? Hello
    ASP.net中提示"分析器错误""未能加载类型" Hello
  • 原文地址:https://www.cnblogs.com/Apare-xzc/p/12243637.html
Copyright © 2020-2023  润新知