单调队列的题目

滑动窗口

https://ac.nowcoder.com/acm/problem/50528

  • 单调队列问题
    a[l],a[l + 1],a[l + 2]....a[r-2],a[r-1],a[r],当这个区间往右移动的时候,只会a[l]离开窗口,a[r + 1]进入窗口,那么我们只需比较这个即可
    典型单调队列题目,我们队列左端存的是当前最优解,当窗口往右移动时,我们看这个队列左端是不是已经不再 k 这个范围内了,如果是的话我们让他出队,然后我们看 a[i] 也就是当前新加的元素 ,如果他比队列中的某些元素小的话,那么他就可能成为后面的最优解,那么我们往前找到一个合适的位置来存储他,也就是他前面的元素都比他小,后面的元素都比他大。
  • 注意队列中存的是他的下标 l = r = 1 开始 ,让第一个元素先进队 注意是 ++ r
    #include<bits/stdc++.h>
    #define pr printf
    #define sc scanf
    #define fur(i,a,b) for(int i = a; i<= b ;i++)
    #define fdr(i,a,b) for(int i = a; i>= b ;i--)
    using namespace std;
    const int N = 1e6 + 5;
    int du[N],n ,k ,a[N];
    typedef long long ll;
    int main()
    {
     // freopen("in.txt","r",stdin);
      sc("%d %d",&n ,&k);
      int l = 1 ,r = 1;
      for(int i = 1 ; i <= n ; i ++){
          sc("%d",&a[i]);
      }
      du[l] = 1;
      if(k ==1)pr("%d ",a[1]);
      for(int i = 2 ; i <= n ;i ++){
          if(i - du[l] >= k && l <= r)l++;
          while(l <= r && a[du[r ]] >=a[i]) r--;
          du[++r] = i; // ++ r 是因为他要在队尾插入
          if(i>=k)pr("%d ",a[du[l]]);
      }
      puts("");
      l = 1, r= 1;
      du[l] = 1;
      if(k ==1)pr("%d ",a[1]);
      for(int i = 2 ; i <= n ;i ++){
          if(i - du[l] >= k && l <= r)l++;
          while(l <= r && a[du[r ]] <=a[i]) r--;
          du[++r] = i;
          if(i>=k)pr("%d ",a[du[l]]);
      }
      puts("");
      return 0;
    }
全部评论

相关推荐

11-15 19:28
已编辑
蚌埠坦克学院 硬件开发
点赞 评论 收藏
分享
11-14 16:13
已编辑
重庆科技大学 测试工程师
Amazarashi66:不进帖子我都知道🐮❤️网什么含金量
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务