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 }
View Code

 

posted @ 2017-05-17 09:31  江屿  阅读(334)  评论(1编辑  收藏  举报