[poj2823]Sliding Window(单调队列)

题意:给定一个序列,求所有滑动窗口内的最值。

解题关键:单调队列裸题,单调递增队列选取最小值,单调递减队列选取最大值。

注意用c++提交,否则会超时。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cstdlib>
 5 #include<iostream>
 6 #include<cmath>
 7 #define maxn 1000005
 8 using namespace std;
 9 typedef long long ll;
10 int n,k;
11 int min1[maxn],max1[maxn],pos1[maxn],que1[maxn],a[maxn];
12 inline int read(){
13     char k=0;char ls;ls=getchar();for(;ls<'0'||ls>'9';k=ls,ls=getchar());
14     int x=0;for(;ls>='0'&&ls<='9';ls=getchar())x=(x<<3)+(x<<1)+ls-'0';
15     if(k=='-')x=0-x;return x;
16 }
17 inline void get_min(int n,int k){
18     int head=0,rear=0;
19     for(int i=1;i<k;i++){
20         while(rear>head&&que1[rear-1]>a[i]) rear--;
21         que1[rear]=a[i];
22         pos1[rear]=i;
23         rear++;
24     }
25     for(int i=k;i<=n;i++){
26         while(rear>head&&que1[rear-1]>a[i]) rear--;
27         que1[rear]=a[i];
28         pos1[rear]=i;
29         rear++;
30         while(pos1[head]<i-k+1) head++;
31         min1[i]=que1[head];
32     }
33 }
34 inline void get_max(int n,int k){
35     int head=0,rear=0;
36     for(int i=1;i<k;i++){
37         while(rear>head&&que1[rear-1]<a[i]) rear--;
38         que1[rear]=a[i];
39         pos1[rear]=i;
40         rear++;
41     }
42     for(int i=k;i<=n;i++){
43         while(rear>head&&que1[rear-1]<a[i]) rear--;
44         que1[rear]=a[i];
45         pos1[rear]=i;
46         rear++;
47         while(pos1[head]<i-k+1) head++;
48         max1[i]=que1[head];
49     }
50 }
51 int main(){
52     while(scanf("%d%d",&n,&k)!=EOF){
53         for(int i=1;i<=n;i++) a[i]=read();
54         get_min(n,k);
55         get_max(n,k);
56         for(int i=k;i<=n;i++){
57             printf("%d%c",min1[i],i==n?'
':' ');
58         }
59         for(int i=k;i<=n;i++){
60             printf("%d%c",max1[i],i==n?'
':' ');
61         }
62     }
63 } 
原文地址:https://www.cnblogs.com/elpsycongroo/p/7639470.html