POJ2823-Sliding Window
Posted -chamgin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ2823-Sliding Window相关的知识,希望对你有一定的参考价值。
给定两个数n和k,接下来给出n个数的数列。每次维护一个长度为k的窗口,求出这个范围的最大值和最小值。每次向右移动一个单位。
考虑如何得出一个区间的最大值,每次增加一个数,如果这个数比当前的最大值小,如何是可以不用维护的。如果比当前值大,那么就要考虑。但是当这个最大值在最左边的时候,它下一次就不能在这个区间了。所以我们要维护的是一个值可以存在的最左的位置。即位置i的生存期最多是i+k,但如果中间出现比它大的数,那么就没必要维护这个数了,可以用出现的数代替它。因为它总是比维护当前的数更优,无论是数值上还是位置上。
也就是说,我们要维护一个递减的数列,可以用单调队列实现做到O(n)的复杂度。
最小值同理,代码如下:
#include <iostream> #include <stdio.h> #include <string.h> #include <queue> #include <algorithm> using namespace std; int n,k,v[2333333],q[23333333]; int main() { while(~scanf("%d%d",&n,&k)){ for(int i=1;i<=n;++i) scanf("%d",&v[i]); int l=1,r=1; q[1]=0; v[0]=1e9; for(int i=1;i<=n+1;++i){ while(l<=r&&q[l]+k<i) ++l; if(i<=k) ; else printf("%d ",v[q[l]]); while(l<=r&&v[q[r]]>=v[i]) --r; q[++r]=i; } puts(""); //printf("%d\n",v[q[l]]); l=1,r=1; q[1]=0; v[0]=-1e9; for(int i=1;i<=n+1;++i){ while(l<=r&&q[l]+k<i) ++l; /* for(int j=l;j<=r;++j) printf("%d ",v[q[j]]); puts(""); */ if(i<=k) ; else printf("%d ",v[q[l]]); while(l<=r&&v[q[r]]<=v[i]) --r; q[++r]=i; } puts(""); //printf("%d\n",v[q[l]]); } return 0; }
以上是关于POJ2823-Sliding Window的主要内容,如果未能解决你的问题,请参考以下文章