首页 > 代码库 > POJ2823 Sliding Window【双端队列】

POJ2823 Sliding Window【双端队列】

求连续的k个中最大最小值,k是滑动的,每次滑动一个

用双端队列维护可能的答案值

如果要求最小值,则维护一个单调递增的序列

对一开始的前k个,新加入的如果比队尾的小,则弹出队尾的,直到新加入的比队尾大,加入队尾

从第k+1个到最后一个,按照上述规则,压入新数,然后弹出队首元素(满足队首元素对应原来序列的位置必须在视窗内,否则,继续弹出下一个)

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;

inline void put(int x){
    if(x< 0){
        putchar('-');
        x = -x;
    }
    if(x == 0){
        putchar('0');
        return;
    }
    char s[20];
    int bas = 0;
    for(;x;x/=10)s[bas++] = x%10+'0';
    for(;bas--;)putchar(s[bas]);
    return;
}


int n,k;
int num[1111111];
int ansmin[1111111];
int pj;
int ansmax[1111111];
int pjj;
struct node
{
	int p,v;
}q[1111111];
int main()
{
	#ifndef ONLINE_JUDGE
		freopen("G:/1.txt","r",stdin);
		freopen("G:/2.txt","w",stdout);
	#endif
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&num[i]);
	}
	int start=1,tail=1;
	for(int i=1;i<=n;i++)
	{
	    if(i==1)
        {
            q[1].v=num[1];
            q[1].p=1;
        }
//		for(int j=tail;j>=start;j--)//弹出比它大的数
//		{
//			if(q[j].v>num[i])
//				tail--;
//		}
		while(tail>=start&&q[tail].v>num[i])
            tail--;
		q[++tail].v=num[i];
		q[tail].p=i;//将该数加到尾巴
		//开始输出最小值
		if(i>=k)
		{
			while(i-q[start].p>k-1) start++;
			ansmin[pj++]=q[start].v;
		}
	}
	start=1;tail=1;
	for(int i=1;i<=n;i++)
	{
	    if(i==1)
        {
            q[1].v=num[1];
            q[1].p=1;
        }
//		for(int j=tail;j>=start;j--)//弹出比它小的数
//		{
//			if(q[j].v<num[i])
//				tail--;
//		}
		while(tail>=start&&q[tail].v<num[i])
            tail--;
		q[++tail].v=num[i];
		q[tail].p=i;//将该数加到尾巴
		//开始输出最小值
		if(i>=k)
		{
			while(i-q[start].p>k-1) start++;
			ansmax[pjj++]=q[start].v;
		}
	}
	for(int i=0;i<pj;i++)
	{
		put(ansmin[i]);
		//printf("%d%c",ansmin[i],i==pj-1?'\n':' ');
		putchar(' ');
	}
	putchar('\n');
	for(int i=0;i<pjj;i++)
	{
		put(ansmax[i]);
		//printf("%d%c",ansmax[i],i==pjj-1?'\n':' ');
		putchar(' ');
	}
	putchar('\n');
}