洛谷 P1886 滑动窗口
题目描述
现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口。现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值。
例如:
The array is [1 3 -1 -3 5 3 6 7], and k = 3.
输入输出格式
输入格式:
输入一共有两行,第一行为n,k。
第二行为n个数(<INT_MAX).
输出格式:
输出共两行,第一行为每次窗口滑动的最小值
第二行为每次窗口滑动的最大值
输入输出样例
输入样例#1:
8 3
1 3 -1 -3 5 3 6 7
输出样例#1:
-1 -3 -3 -3 3 3
3 3 5 5 6 7
说明
50%的数据,n<=10^5
100%的数据,n<=10^6
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #define N 10000000
5 using namespace std;
6 int n,k,a[N],q[N],p[N];
7 void MIN()
8 {
9 int head=1,tail=0;
10 for(int i=1;i<k;i++)
11 {
12 while(head<=tail&&q[tail]>=a[i])
13 tail--;
14 q[++tail]=a[i];
15 p[tail]=i;
16 }
17 for(int i=k;i<=n;i++)
18 {
19 while(head<=tail&&q[tail]>=a[i])
20 tail--;
21 q[++tail]=a[i];
22 p[tail]=i;
23 while(p[head]<=i-k)
24 head++;
25 printf("%d ",q[head]);
26 if(i==n) printf("\n");
27 }
28 }
29 void MAX()
30 {
31 int head=1,tail=0;
32 for(int i=1;i<k;i++)
33 {
34 while(head<=tail&&q[tail]<=a[i])
35 tail--;
36 q[++tail]=a[i];
37 p[tail]=i;
38 }
39 for(int i=k;i<=n;i++)
40 {
41 while(head<=tail&&q[tail]<=a[i])
42 tail--;
43 q[++tail]=a[i];
44 p[tail]=i;
45 while(p[head]<=i-k)
46 head++;
47 printf("%d ",q[head]);
48 if(i==n) printf("\n");
49 }
50 }
51 int main()
52 {
53 cin>>n>>k;
54 for(int i=1;i<=n;i++)
55 cin>>a[i];
56 MIN();
57 MAX();
58
59 return 0;
60 }
思路:单调队列~~