滑动窗口
题目大意
在一个长度为n的序列中滑动着一个k大小的窗口,我们要求窗口中的最大值和最小值
思路
我们要求这个窗口中的最大值和最小值那么我们用一个单调栈来储存
1.在求最大的函数中,我们建立一个单调递减的栈,用q1数组来储存栈中每个数字的位置,每次窗口滑动,如果储存最大的单调栈的head的位置不在窗口内,我们就要将其弹出,同样的,如果有一个入栈的数大于tail,那么我们就将tail弹出,直到找到一个适合的位置,而我们所要输出的值就是a[q1[head]]的值...
2.在求最小的函数中,相应的我们建立一个单调递增的函数,用q2数组来储存栈中每个数字的位置,其余的同上
反思
我自己做这个题目时可谓是漏洞百出,主要是我的快读出现了BUG,我连-号都没有读入,闹了好大的笑话,还耽误了GQL大佬的时间
代码(来自一个不是很喜欢压行的蒟蒻)
#include<bits/stdc++.h> using namespace std; int n,m; int a[1000008]; int q1[1000008]; int q2[1000005];//用来记录位置的 int scan()//更新的快读 { int as=0; bool y=1; char c=getchar(); while(c!='-'&&(c>'9'||c<'0')) c=getchar(); if(c=='-') y=0,c=getchar(); while(c>='0'&&c<='9') as=(as<<3)+(as<<1)+(c^'0'),c=getchar(); return y?as:-as; } void minn() { int h=1,tail=0; for(int i=1;i<=n;i++) { while(h<=tail&&i-q1[h]>=m) h++; while(h<=tail&&a[i]<a[q1[tail]]) tail--; q1[++tail]=i; if(i>=m) printf("%d ",a[q1[h]]); } } void maxx() { int h=1,tail=0; for(int i=1;i<=n;i++) { while(h<=tail&&i-q2[h]>=m) h++; while(h<=tail&&a[i]>a[q2[tail]]) tail--; q2[++tail]=i; if(i>=m) printf("%d ",a[q2[h]]); } } int main() { cin>>n>>m; for(int i=1;i<=n;i++) { a[i]=scan(); } minn(); cout<<endl; maxx(); }