题目链接:http://http://poj.org/problem?id=2823
题意:
给出一个有n个数组成的数组和已知大小的滑动窗口
窗口每个时刻向后移动一位,求每个窗口的最大值和最小值
解题思路:
最大值:单调递减的队列。当窗口往后移动一位时,从队尾开始不断的删除比新增加的数小的数,相等的也删去。队头的位置如果小于i-k+1,那么也要删去,因为它不在这个窗口内
最小值:单调递增的队列。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
#define inf 1000005
struct node
{
int val,id;
};
node maxque[inf],minque[inf];
int maxhead,maxtail,minhead,mintail;
int pa[inf],pi[inf];
int main()
{
int n,k,a;
scanf("%d%d",&n,&k);
maxhead=maxtail=0;
minhead=mintail=0;
for(int i=0;i<k;i++)
{
scanf("%d",&a);
while(minhead<mintail && minque[mintail-1].val>=a) mintail--;
minque[mintail].val=a;
minque[mintail].id=i;
mintail++;
while(maxhead<maxtail && maxque[maxtail-1].val<=a) maxtail--;
maxque[maxtail].val=a;
maxque[maxtail].id=i;
maxtail++;
}
int la=0;
for(int i=k;i<n;i++)
{
pi[la] = minque[minhead].val;
pa[la] = maxque[maxhead].val;
la++;
scanf("%d",&a);
while(minque[minhead].id<i-k+1 && minhead<mintail) minhead++;
while(minhead<mintail && minque[mintail-1].val>=a) mintail--;
minque[mintail].val=a;
minque[mintail].id=i;
mintail++;
while(maxque[maxhead].id<i-k+1 && maxhead<maxtail) maxhead++;
while(maxhead<maxtail && maxque[maxtail-1].val<=a) maxtail--;
maxque[maxtail].val=a;
maxque[maxtail].id=i;
maxtail++;
}
pa[la] = maxque[maxhead].val;
pi[la] = minque[minhead].val;
for(int i=0;i<=la;i++)
{
if(i!=la) printf("%d ",pi[i]);
else printf("%d\n",pi[i]);
}
for(int i=0;i<=la;i++)
{
if(i!=la) printf("%d ",pa[i]);
else printf("%d\n",pa[i]);
}
return 0;
}