Time Limit: 12000MS | Memory Limit: 65536K | |
Case Time Limit: 5000MS |
Description
Window position | Minimum value | Maximum value |
---|---|---|
[1 3 -1] -3 5 3 6 7 | -1 | 3 |
1 [3 -1 -3] 5 3 6 7 | -3 | 3 |
1 3 [-1 -3 5] 3 6 7 | -3 | 5 |
1 3 -1 [-3 5 3] 6 7 | -3 | 5 |
1 3 -1 -3 [5 3 6] 7 | 3 | 6 |
1 3 -1 -3 5 [3 6 7] | 3 | 7 |
Your task is to determine the maximum and minimum values in the sliding window at each position.
Input
Output
Sample Input
8 3 1 3 -1 -3 5 3 6 7
Sample Output
-1 -3 -3 -3 3 3 3 3 5 5 6 7
给定一个大小已知的数组以及一个大小已知的滑动窗口,窗口每个时刻向后移动一位,求出每个时刻窗口中数字的最大值和最小值。
这个题是单调队列的入门题。
求最大值:建立一个单调递减队列,元素从左到右依次入队,入队之前必须从队列尾部开始删除那些比当前入队元素小或者相等的元素,直到遇到一个比当前入队元素大的元素,或者队列为空为止。若此时队列的大小超过窗口值,则从队头删除元素,直到队列大小小入窗口值为止。然后把当前元素插入队尾。
求最小值:建立一个单调递增队列,元素从左到右依次入队,入队之前必须从队列发问开始删除那些比当前入队元素大或者相等的元素,直到遇到一个比当前入队元素小的元素,或者队列为空为止。若此时队列的大小超过窗口值,则从队头删除元素,直到队列大小小入窗口值为止。然后把当前元素插入队尾。
AC:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn= 1000005; struct node { int val; int pos; }; int n,k,win[maxn],maxhead,maxtail,minhead,mintail; int Max[maxn],Min[maxn],cnt; node maxque[maxn],minque[maxn]; void initQue() { maxhead = maxtail = 0; minhead = mintail = 0; cnt = 0; for(int i = 1; i <= k; i++) { while(maxhead != maxtail && win[i] > maxque[maxtail-1].val) maxtail--; maxque[maxtail].val = win[i]; maxque[maxtail].pos = i; maxtail++; while(minhead != mintail && win[i] < minque[mintail-1].val) mintail--; minque[mintail].val = win[i]; minque[mintail].pos = i; mintail++; } Max[++cnt] = maxque[maxhead].val; Min[cnt] = minque[minhead].val; } void Sliding_Window() { for(int i = k+1; i <= n; i++) { //找出当前区间最大值 while(maxhead != maxtail && win[i] > maxque[maxtail-1].val) maxtail--; maxque[maxtail].val = win[i]; maxque[maxtail].pos = i; maxtail++; while(maxhead != maxtail && i - maxque[maxhead].pos + 1 > k) maxhead++; Max[++cnt] = maxque[maxhead].val; //找出当前区间最小值 while(minhead != mintail && win[i] < minque[mintail-1].val) mintail--; minque[mintail].val = win[i]; minque[mintail].pos = i; mintail++; while(minhead != mintail && i - minque[minhead].pos + 1 > k) minhead++; Min[cnt] = minque[minhead].val; } } void print() { for(int i = 1; i <= cnt; i++) printf("%d ",Min[i]); printf("\n"); for(int i = 1; i <= cnt; i++) printf("%d ",Max[i]); printf("\n"); } int main() { while(scanf("%d%d",&n,&k)!=EOF) { for(int i = 1; i <= n; i++) scanf("%d",&win[i]); initQue(); Sliding_Window(); print(); } return 0; }