Time Limit: 12000MS | Memory Limit: 65536K | |
Total Submissions: 24525 | Accepted: 7206 | |
Case Time Limit: 5000MS |
Description
Window position | Minimum value | Maximum 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 |
Your task is to determine the maximum and minimum values in the sliding window at each position.
Input
Output
Sample Input
8 3 1 3 -1 -3 5 3 6 7
Sample Output
-1 -3 -3 -3 3 3 3 3 5 5 6 7
Source
POJ Monthly--2006.04.28, Ikki
/*维护一个不增的双向队列求最大值 维护一个不降的双向队列求最小值*/ #include<iostream> #include<cstring> #include<cmath> #include<cstdio> #define N 1000005 using namespace std; int a[N],zhan[N]; int n,k; void find_min() //求最小值 { int head=0,tail=1; zhan[1]=1; for(int i=2;i<=k-1;i++) { if(a[i]<=a[zhan[head+1]]) { head=tail; zhan[++tail]=i; } else { while(tail!=head && a[zhan[tail]]>=a[i]) tail--; zhan[++tail]=i; } } for(int i=k;i<=n;i++) { if(tail-head==k) head++; if(a[i]<=a[zhan[head+1]]) { head=tail; zhan[++tail]=i; } else { while(tail!=head && a[zhan[tail]]>=a[i]) tail--; zhan[++tail]=i; } while(zhan[head+1]<=i-k) head++; printf("%d",a[zhan[head+1]]); if(i!=n) printf(" "); } printf("\n"); } void find_max() //求最大值 { int head=0,tail=1; zhan[1]=1; for(int i=2;i<=k-1;i++) { if(a[i]>=a[zhan[head+1]]) { head=tail; zhan[++tail]=i; } else { while(tail!=head && a[zhan[tail]]<=a[i]) tail--; zhan[++tail]=i; } } for(int i=k;i<=n;i++) { if(tail-head==k) head++; if(a[i]>=a[zhan[head+1]]) { head=tail; zhan[++tail]=i; } else { while(tail!=head && a[zhan[tail]]<=a[i]) tail--; zhan[++tail]=i; } while(zhan[head+1]<=i-k) head++; printf("%d",a[zhan[head+1]]); if(i!=n) printf(" "); } printf("\n"); } int main() { while(scanf("%d%d",&n,&k)!=EOF) { if(k>n) k=n; memset(a,0,sizeof(a)); for(int i=1;i<=n;i++) scanf("%d",&a[i]); find_min(); find_max(); } return 0; }