POJ 2823 Sliding Window 滑动窗口 单调队列优化

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

灵感来源:单调队列初步

为什么说是灵感来源呢,看了紫书上的代码,知道了单调队列的意思,而且有两种解法,一种是用C++的set,复杂度是O((N-k) log k),然后百度到了此题,为了方便用来set,然后果断TLE。就试着写单调队列,可是却写不出来。。百度到这篇博客后,第一次随便过了一遍,没怎么看懂。没看了。今天再次百度到这篇博文,又准备大概过一篇(没看代码),浏览过程中,灵感偶然来啦:单调队列中存储的值是不是不是原数组的值,而是原数组中的下标呢?这样队首的位置的删除就且不是容易多了?!!!带着这样的想法,果然容易写多了。。顺利AC,祝贺吧!

谈谈单调队列吧:所谓的单调队列,顾名思义就是一个队列,其存储的值是单调性的。对就是这么简单,但是得注意点是,这个单调队列存储的并不是其值,而是其值所在原数组中的下标(刚开始,我想错了),这样才好更新队首的值。详情请看上面链接或紫书P241。

代码:

#include
#include
#define maxn 1000010

using namespace std;

int A[maxn],N,K;
int Q[maxn],front,rear;

void solve(int op){//op为0是求最小值,为1时求最大值
    Q[0]=0;front=0;rear=1;//存所在原数组的下标
    if(K==1) printf("%d ",A[0]);
    for(int i=1;i=front && A[i]<=A[Q[rear-1]]) rear--;//删除多余的数
        else while(rear-1>=front && A[i]>=A[Q[rear-1]]) rear--;//注意这里&&后面的比较含等号
        Q[rear++]=i;
        if(i-K+1>Q[front]) front++;
        if(i>=K-1) printf("%d ",A[Q[front]]);
    }
    printf("\n");
}

int main(){
    cin>>N>>K;
    for(int i=0;i


你可能感兴趣的:(POJ题解,数据结构,UVA(&紫书))