赞
踩
P1886 滑动窗口 /【模板】单调队列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
参考:第九章:单调栈与单调队列_单调栈和单调队列-CSDN博客
练习一下单调队列模板,后面有些题好做一些。
步骤(来自上面的参考文章):
注意:
1.以求最大值为例,弹出窗口尾部的小于将要入队的元素的部分是用while,因为可能不止当前尾部一个小于将要入队的元素,要全部弹出保持单调。
2.i-k+1其实对应的就是窗口的编号,i-k+1>=0的时候,i每次滑动一个单位,就会产生一个窗口。
3.记得判断h<=t,需要保证队伍不为空 才能对队列元素做查询和操作
4.队列存储下标,更加方便
5.不要忘了新元素进队
- #include<bits/stdc++.h>
- #define int long long
- #define endl '\n'
- using namespace std;
- const int N=1e6+10;
- int ans=0;
- int q[N];
- int mx[N],mn[N];
- signed main() {
-
- ios::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);
-
- int n,k;
- cin>>n>>k;
-
- vector<int> a(n,0);
-
- for(int i=0;i<n;i++){
- cin>>a[i];
- }
-
-
- // 当tail>=head时,说明有元素。而一开始队列为空
- int h=0,t=-1;
- //求最大
- for(int i=0;i<n;i++){
-
- //需要保证队伍不为空
- //队头元素已经不在窗口内,弹出
- if(h<=t&&q[h]<i-k+1){
- h++;
- }
-
- //这个地方是while ,为了保持单调,要把窗口内 比当前要入队的元素 小的全部弹出
- //尾元素比将要入队的 小,那么滑动窗口框着这个尾元素的时候也会框着他后面这个比他大的数,注定不能是窗口里的最大值
- //所以出队
- while(h<=t&&a[q[t]]<a[i]){
- t--;
- }
- q[++t]=i;
- if(i-k+1>=0)
- mx[i-k+1]=a[q[h]];
- }
-
-
- //最小
- h=0,t=-1;
- for(int i=0;i<n;i++){
-
- if(h<=t&&q[h]<i-k+1){
- h++;
- }
-
- //这个地方是while
- while(h<=t&&a[q[t]]>a[i]){
- t--;
- }
- q[++t]=i;
- if(i-k+1>=0)
- mn[i-k+1]=a[q[h]];
- }
-
- for(int i=0;i<n-k+1;i++){
-
- cout<<mn[i]<<" ";
- }
- cout<<endl;
-
- for(int i=0;i<n-k+1;i++){
-
- cout<<mx[i]<<" ";
- }
-
- return 0;
- }
-
-
-
-
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。