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( "\n"); printf( "%d", a2[k-1] ); for( j=k; j<i; j++ ) { printf( " %d", a2[j] ); }//输出最大数 printf( "\n"); } return 0; }