【题目描述】
给定一个长度为N的数组,一个长为K的滑动窗体从最左端移至最右端,移动时只能看到窗体内的K个数,每次窗体向右移动一位,如下表:
Window position | Min value | Max 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 |
现要求找出窗体在各位置时的Max value与Min value。
【输入描述】
第一行输入两个整数N、K;
第二行输入长度为N的数组。
【输出描述】
第一行输出每个位置的Min value;
第二行输出每个位置的Max value。
【样例输入】
8 3
1 3 -1 -3 5 3 6 7
【样例输出】
-1 -3 -3 -3 3 3
3 3 5 5 6 7
【数据范围及提示】
对于20%的数据,n <= 500;
对于50%的数据,n <= 100000;
对于100%的数据,n <= 1000000。
源代码: #include<cstdio> int n,k,i[1000001],Q[1000001],P[1000001]; void Min() { int Head=1,Tail=0; for (int a=0;a<k-1;a++) //初始化。 { while (Head<=Tail&&Q[Tail]>=i[a]) Tail--; Q[++Tail]=i[a]; P[Tail]=a; } for (int a=k-1;a<n;a++) //移动状态。 { while (Head<=Tail&&Q[Tail]>=i[a]) //增尾。 Tail--; Q[++Tail]=i[a]; P[Tail]=a; while (P[Head]<a-k+1) //去头。 Head++; printf(a==n-1?"%d ":"%d ",Q[Head]); //注意换行。 } } void Max() //同理于上。 { int Head=1,Tail=0; for (int a=0;a<k-1;a++) { while (Head<=Tail&&Q[Tail]<=i[a]) Tail--; Q[++Tail]=i[a]; P[Tail]=a; } for (int a=k-1;a<n;a++) { while (Head<=Tail&&Q[Tail]<=i[a]) Tail--; Q[++Tail]=i[a]; P[Tail]=a; while (P[Head]<a-k+1) Head++; printf(a==n-1?"%d ":"%d ",Q[Head]); } } int main() //裸单调队列。 { scanf("%d%d",&n,&k); for (int a=0;a<n;a++) scanf("%d",&i[a]); Min(); Max(); return 0; }