sliding window poj

  这个题主要用的还是单调队列,大体思路如下:

  1.创建两个<deque>型队列q1,q2;

  2.将每个窗口里的最小数用q1求出,最大数用q2求出,并且将其存入两个数组中;

  3.输出两个数组。

注:

  • 单调队列:比如严格单调不增的队列,队列为空或新增元素小于队尾元素时,将其放入队尾;否则一直将队尾元素出队,再将新增元素入队;当队首元素不符合要求(不在窗口中)时也将其删除。
  • <deque>:能在队首和队尾对元素进行操作,在此题的应用上较为方便。
#include<iostream>
#include<deque>
#include<stdio.h>
using namespace std;
deque<int>q1,q2;
//q1为单调不减队列、q2为单调不增队列
#define max 1000002
int a[max];
int a1[max], a2[max];
//存放最大数、最小数的数组
int main()
{
    int n, k;//数组大小、窗口大小
    int i, j;
    while( scanf( "%d%d", &n, &k )!=EOF )
    { 
        for( i=0; i<n; i++ )
            scanf( "%d", &a[i] );
        q1.clear();
        q2.clear();
        for( i=0; i<n; i++ )
        {            
            while( !q1.empty()&&a[i]<a[q1.back()] )
                q1.pop_back();//队列不空、队尾元素大于a[i]
            while( !q1.empty()&&i-k+1>q1.front() )
                q1.pop_front();//队首元素不在窗口中
            q1.push_back(i);
            a1[i]=a[q1.front()];
            //单调不增队列的操作
            while( !q2.empty()&&a[i]>a[q2.back()] )
                q2.pop_back();//队列不空、队尾元素小于a[i]
            while( !q2.empty()&&i-k+1>q2.front() )
                q2.pop_front();//队首元素不在窗口中
            q2.push_back(i);
            a2[i]=a[q2.front()];
            //单调不减队列的操作
        }

        printf( "%d", a1[k-1] );
        for( j=k; j<i; j++ )
        {
            printf( " %d", a1[j] );
        }//输出最小数
        printf( "
");
        printf( "%d", a2[k-1] );
        for( j=k; j<i; j++ )
        {
            printf( " %d", a2[j] );                
        }//输出最大数
        printf( "
");
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/so-easy/p/3482816.html