POJ2823 滑动窗口
滑动最小(最大)值,模版题。
题意:给一个数列,给一个窗口大小k,顺序求每个窗口中最大值和最小值。
和挑战中的例题一模一样,就多了一个求最大,改个大于小于符号就行。
算法是利用双端队列:
以求最小值为例,维护这样一个队列:
1.队列中元素保存数列下标,数列中元素(下标)递增,并且下标对应数列中元素(下标对应值)也递增。
显然我们i从0开始遍历保证了队列中保存的下标是递增的,我们只需要设计算法保证下标对应数列中元素也递增即可。
2.加入一个下标时,从后往前删掉所有对应值大于当前下标对应值的下标,使得下标对应元素也能递增。
3.将这个下标加入队列
4.如果队列首位元素在后面不再需要用到了,队列首位后移一位。
举例
n=5
k=3
a={1,3,5,4,2}
加入0 -> {0}
加入1 -> {0,1}
加入2 -> {0,1,2}
当前窗口最小值=a0=1
删除0 -> {1,2}
加入3 -> {1,3} (a2>=a3,删除2)
当前窗口最小值=a1=3
删除1 -> {3}
加入4 -> {4} (a3>=a4,删除3)
当前窗口最小值=a4=2
Description
The array is [1 3 -1 -3 5 3 6 7], and k is 3.
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
1 #include<iostream> 2 #include <cstdio> 3 #define MAX_N 1000000 + 16 4 5 using namespace std; 6 int x[MAX_N]; 7 int b[MAX_N],c[MAX_N]; 8 int que[MAX_N]; 9 int l,r; 10 int main(int argc, char *argv[]) 11 { 12 int n,k; 13 cin >> n >> k; 14 for(int i=0; i<n; i++) 15 cin >> x[i]; 16 l=r=0; 17 for(int i=0; i<n; i++) 18 { 19 while(l<r&&x[que[r-1]]>=x[i] )r--; 20 que[r++]=i; 21 22 if(i-k+1>=0) 23 { 24 b[i-k+1]=x[que[l]]; 25 26 if(que[l]==i-k+1) 27 { 28 l++; 29 } 30 } 31 } 32 l=r=0; 33 for(int i=0; i<n; i++) 34 { 35 while(l<r&&x[que[r-1]]<=x[i] )r--; 36 que[r++]=i; 37 38 if(i-k+1>=0) 39 { 40 c[i-k+1]=x[que[l]]; 41 42 if(que[l]==i-k+1) 43 { 44 l++; 45 } 46 } 47 } 48 for(int i=0; i<=n-k; i++) 49 printf("%d%c",b[i],i==n-k?'\n':' '); 50 for(int i=0; i<=n-k; i++) 51 printf("%d%c",c[i],i==n-k?'\n':' '); 52 return 0; 53 }
posted on 2018-05-03 21:41 Best_Efforts 阅读(207) 评论(0) 编辑 收藏 举报