(这道题也是滑动窗口.jpg
这题的题意呢是说有一个长为n的数组和一个长度为m的滑动窗口,在初始阶段窗口大小是可以<m的,要我们求每次滑动窗口之后窗口里的最小值
滑动窗口题,可以用map解(费时)也可以用单调队列(不是优先队列!!)
在我的上一篇题解洛谷P3032扫描–题解中描述了用map的方法,但是对于这道题来说map会爆内存,也会爆T,所以采用单调队列
这里因为关系到窗口的大小,会定义一个结构体变量
struct node {
int val, num;
};
整体的思路就是每次滑动的时候都检查队列的尾部,把所有值>a[i].val的给pop出去
pop完成后把a[i]放入队列中
最后检查队首有没有下标太靠前的,也需要pop出去
处理都完成之后就可以输出啦!
因为题目要求的是对于i这个位置,i之前的数的最小值,所以从0开始只需要进行到n-1即可
顺带一提,这里用cin和cout会T两个点
那么。。。喜闻乐见,上代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e6+10;
const int mod=1e9+7;
const int inf=INT_MAX;
struct node {
int val, num;
};
node a[maxn];
int main()
{
ios::sync_with_stdio(false);
int n, k;
scanf("%d%d", &n, &k);
for(int i=0; i<n; i++){
scanf("%d", &a[i].val);
a[i].num=i;
}
deque<node> q;
printf("0");
for(int i=0; i<n-1; i++){
if(q.size()==k) q.pop_front();
while(!q.empty()&&(a[i].val<=q.back().val)) q.pop_back();
q.push_back(a[i]);
while(!q.empty()&&q.front().num<=i-k) q.pop_front();
printf("\n%d", q.front().val);
}
return 0;
}