P1886 滑动窗口
滑动窗口
题目描述:
现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口。现在这个窗口从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值。
思路:
直接单调队列搞上,但需要两个单调队列,一个存最小值,一个存最大值,还要有数组来保存它的下标,以计算这个数是否还在窗口之中。
代码:
1 #include<cstdio> 2 #define N 1000010 3 int quemaxx[N],quemaxy[N],queminx[N],queminy[N],a[N]; 4 int n,m,endmax,beginmax,endmin,beginmin; 5 int main(){ 6 scanf("%d%d",&n,&m); 7 for(int i=1;i<=n;++i) 8 scanf("%d",&a[i]); 9 queminx[++endmin]=a[1]; 10 queminy[endmin]=1; 11 for(int i=2;i<m;++i){ 12 while(a[i]<queminx[endmin]&&endmin){ 13 endmin--; 14 beginmin--; 15 } 16 endmin++; 17 queminx[endmin]=a[i]; 18 queminy[endmin]=i; 19 } 20 for(int i=m;i<=n;++i){ 21 while(a[i]<queminx[endmin]&&endmin){ 22 endmin--; 23 beginmin--; 24 } 25 endmin++; 26 queminx[endmin]=a[i]; 27 queminy[endmin]=i; 28 while(i-queminy[beginmin]>m-1) 29 beginmin++; 30 printf("%d ",queminx[beginmin]); 31 } 32 printf("\n"); 33 quemaxx[++endmax]=a[1]; 34 quemaxy[endmax]=1; 35 for(int i=2;i<m;++i){ 36 while(a[i]>quemaxx[endmax]&&endmax){ 37 beginmax--; 38 endmax--; 39 } 40 endmax++; 41 quemaxx[endmax]=a[i]; 42 quemaxy[endmax]=i; 43 } 44 for(int i=m;i<=n;++i){ 45 while(a[i]>quemaxx[endmax]&&endmax){ 46 beginmax--; 47 endmax--; 48 } 49 endmax++; 50 quemaxx[endmax]=a[i]; 51 quemaxy[endmax]=i; 52 while(i-quemaxy[beginmax]>m-1) 53 beginmax++; 54 printf("%d ",quemaxx[beginmax]); 55 } 56 return 0; 57 }