POJ 2823(单调队列 手动模拟+deque两种方法)

题目链接:http://poj.org/problem?id=2823

 

题目大意:有n个数字,从左至右输出每个长度为m的数列段的最小值和最大值

 

题目思路:经典滑窗最值问题。首先先对前m-1个数字建立单调队列,以最大为例,单调队列就是从队尾插入,遇到小于等于该数字的就把他删掉,直到删光或者遇到比他大的数字。对于m到n个数字,每插入一个数字维护完后的队首就是想要的答案。这里的维护分为两步。第一步是观察队首对应数字所在的位置。如果队首不在考察范围内,那就把它踢出去,第二步的插入跟之前的一模一样,复制粘贴即可。然后每次都记录答案就行。

 

以下是手动模拟版代码:

#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cstdio>
using namespace std;
#define inf 0x3f3f3f3f
#define MAXN 1000005
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
struct node{
    int pos,val;
}maxque[MAXN],minque[MAXN];
int minans[MAXN],maxans[MAXN];
int main(){
    int n,k,x;
    while(~scanf("%d%d",&n,&k)){
        int maxhead=1,maxtail=1;
        int minhead=1,mintail=1;
        rep(i,1,k-1){
            scanf("%d",&x);
            while(maxhead<maxtail&&maxque[maxtail-1].val<=x)maxtail--;
            while(minhead<mintail&&minque[mintail-1].val>=x)mintail--;
            maxque[maxtail].pos=i;maxque[maxtail++].val=x;
            minque[mintail].pos=i;minque[mintail++].val=x;
        }
        rep(i,k,n){
            while(maxhead<maxtail&&maxque[maxhead].pos<i-k+1)maxhead++;
            while(minhead<mintail&&minque[minhead].pos<i-k+1)minhead++;
            scanf("%d",&x);
            while(maxhead<maxtail&&maxque[maxtail-1].val<=x)maxtail--;
            while(minhead<mintail&&minque[mintail-1].val>=x)mintail--;
            maxque[maxtail].pos=i;maxque[maxtail++].val=x;
            minque[mintail].pos=i;minque[mintail++].val=x;
            maxans[i]=maxque[maxhead].val;
            minans[i]=minque[minhead].val;
        }
        rep(i,k,n){
            printf("%d%c",minans[i],i==n?'\n':' ');
        }
        rep(i,k,n){
            printf("%d%c",maxans[i],i==n?'\n':' ');
        }
    }
    return 0;
}

 

 

deque很好用 stl真香 但是用deque需要9秒,但是手动模拟只用5秒...

 

以下是deque代码:

#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<list>
using namespace std;
#define inf 0x3f3f3f3f
#define MAXN 1000005
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
struct node{
    int pos,val;
}a;
deque<node>maxq,minq;
int maxans[MAXN],minans[MAXN];
int main(){
    int n,k,x;
    while(~scanf("%d%d",&n,&k)){
        while(!maxq.empty())maxq.pop_back();
        while(!minq.empty())minq.pop_back();
        rep(i,1,k-1){
            scanf("%d",&x);
            while(!maxq.empty()&&maxq.back().val<=x)maxq.pop_back();
            while(!minq.empty()&&minq.back().val>=x)minq.pop_back();
            a.pos=i,a.val=x;
            maxq.push_back(a);
            minq.push_back(a);
        }
        rep(i,k,n){
            while(!maxq.empty()&&maxq.front().pos<i-k+1)maxq.pop_front();
            while(!minq.empty()&&minq.front().pos<i-k+1)minq.pop_front();
            scanf("%d",&x);
            while(!maxq.empty()&&maxq.back().val<=x)maxq.pop_back();
            while(!minq.empty()&&minq.back().val>=x)minq.pop_back();
            a.pos=i,a.val=x;
            maxq.push_back(a);
            minq.push_back(a);
            maxans[i]=maxq.front().val;
            minans[i]=minq.front().val;
        }
        rep(i,k,n){
            printf("%d%c",minans[i],i==n?'\n':' ');
        }
        rep(i,k,n){
            printf("%d%c",maxans[i],i==n?'\n':' ');
        }
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值