Poj2823 单调队列

题目大意:

给你一个数字序列,然后给一个从左到右滑动的窗口,窗口的长度是k,一次向右移动一格,每次输出这个窗口中最大的数和最小的数,问最后输出的序列是什么.

思路:

维护两个单调队列,一个维护最大值,一个维护最小值.

因为窗口移动的方向是一直朝一个方向的,所以可以用单调队列维护这个最大值,队列中记录的是最大的那个数的下标.

每向右移动一次,前面出去一个元素,后面进来一个元素,然后维护队列的单调性.

AC代码:

  1 //6000ms 1Y 单调队列 需要维护两个单调队列 每一个需要维护它们的开始和结束元素的位置,用一个万能元素当第一个元素,当比较到它时必将
  2 //被替换,每一个单调队列中的元素都记录一个作用时间域. 每个元素进队一次出队一次 所以O(n)
  3 #include <iostream>
  4 #include <cstdio>
  5 #include <string.h>
  6 #include <stdlib.h>
  7 #include <math.h>
  8 #include <vector>
  9 #include <algorithm>
 10 struct node{
 11    int time,v;
 12 };
 13 using namespace std;
 14 #define maxn 1000005
 15 #define INF 0x7fffffff
 16 node maxque[maxn],minque[maxn];
 17 int minquelen,maxquelen,minquestart,maxquestart,i,j;
 18 int printmin[maxn],printmax[maxn];
 19 void insertmax(int v)
 20 {
 21     int q;
 22     for(q=maxquelen;q>=0;q--)
 23      if(maxque[q].v>v) {maxquelen=q+1;maxque[maxquelen].v=v;maxque[maxquelen].time=j;break;}
 24 }
 25 void insertmin(int v)
 26 {
 27     int q;
 28     for(q=minquelen;q>=0;q--)
 29      if(minque[q].v<v) {minquelen=q+1;minque[minquelen].v=v;minque[minquelen].time=j;break;}
 30 }
 31 int querymax()
 32 {
 33     if(i<maxque[maxquestart+1].time)
 34      return maxque[maxquestart+1].v;
 35     else
 36      if(i==maxque[maxquestart+1].time)
 37      {
 38        int temp=maxque[maxquestart+1].v;
 39        maxque[++maxquestart]=maxque[0];
 40        return temp;
 41      }
 42      else
 43      {
 44          maxque[++maxquestart]=maxque[0];
 45          return querymax();
 46      }
 47 }
 48 int querymin()
 49 {
 50     if(i<minque[minquestart+1].time)
 51      return minque[minquestart+1].v;
 52     else
 53      if(i==minque[minquestart+1].time)
 54      {
 55        int temp=minque[minquestart+1].v;
 56        minque[++minquestart]=minque[0];
 57        return temp;
 58      }
 59      else
 60      {
 61         minque[++minquestart]=minque[0];
 62         return querymin();
 63      }
 64 }
 65 int main()
 66 {
 67     //freopen("in.txt","r",stdin);
 68     int n,k;
 69     while(~scanf("%d%d",&n,&k))
 70     {
 71         int x;
 72         if(k>n) k=n;
 73         maxque[0].v=INF;minque[0].v=-INF;
 74         minquelen=maxquelen=minquestart=maxquestart=0;
 75         for(i=1;i<k;i++)
 76         {
 77          j=i;
 78          scanf("%d",&x);
 79          insertmax(x);
 80          insertmin(x);
 81          //cout<<"i="<<i<<" x="<<x<<endl;
 82         }
 83         /*cout<<"minquestart="<<minquestart<<endl;
 84         for(int t=1;t<=minquelen;t++)
 85          cout<<"minque["<<t<<"].v="<<minque[t].v<<" minque["<<t<<"].time="<<minque[t].time<<endl;
 86         cout<<"maxquestart="<<maxquestart<<endl;
 87         for(int t=1;t<=maxquelen;t++)
 88          cout<<"maxque["<<t<<"].v="<<maxque[t].v<<" maxque["<<t<<"].time="<<maxque[t].time<<endl;
 89         */
 90         //cout<<"adsf"<<endl;
 91         for(i=1;i<=n-k+1;i++) //n-k
 92         {
 93           //cout<<"adsf"<<endl;
 94           j=i+k-1;
 95           scanf("%d",&x);
 96           insertmax(x);
 97           insertmin(x);
 98           printmax[i]=querymax();
 99           printmin[i]=querymin();
100           //cout<<"1"<<endl;
101           //cout<<"querymax()="<<printmax[i]<<endl;
102           //cout<<"querymin()="<<printmin[i]<<endl;
103         }
104         for(i=1;i<=n-k+1;i++)
105         {
106          if(i!=1) printf(" ");
107          printf("%d",printmin[i]);
108         }
109         printf("\n");
110         for(i=1;i<=n-k+1;i++)
111         {
112          if(i!=1) printf(" ");
113          printf("%d",printmax[i]);
114         }
115         printf("\n");
116     }
117     return 0;
118 }

View Code

posted on 2014-10-16 13:49 Lonely patients 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/Acmerfighting/p/4028624.html

Poj2823 单调队列相关推荐

  1. POJ2823 Sliding Window 单调队列

    题目大意 给出一段序列,一个长度一定的窗口从左到右滑动.求窗口滑动到每个位置时窗口内数字的最大值.最小值各是多少.n<=1e6. 总体思路 遇到这种对一个沿着一个方向滑动的区间求最值问题,可以运 ...

  2. POJ2823 滑动窗口 单调队列模板题 第一次用了发函数指针

    题意 有一个n长的序列,用k长的窗口在上面滑动,去每次窗口中最小和最大的数. 思路 使用单调队列,维护这个队列是单调的.以取最小元素为例,若窗口内左边元素>=右边元素,则左边元素失去保留的意义, ...

  3. 洛谷 - P1886 滑动窗口(单调队列/线段树)

    题目链接:点击查看 题目大意:给出一个由n个数构成的序列,再给出一个长度为k的窗口,这个窗口从第一个下标开始一直向后移动,每次移动一个单位,每次移动询问一次该窗口中的最大值和最小值,最后输出答案 题目 ...

  4. [summary] 单调队列

    2019独角兽企业重金招聘Python工程师标准>>> 很久没做单调队列了╮(╯_╰)╭ 已经不太会了.... 单调队列究其本质就是队列,加上队尾可以删除. 队列都是从队尾插入,队首 ...

  5. 单调栈与单调队列简单例题

    单调栈与单调队列简单例题 单调栈: POJ3250 题意:有n只奶牛排成一列向右看,每头奶牛只能看到比自己矮的奶牛,即会被高的奶牛挡住后面,问共有多少只奶牛能被看到 思路:考虑每头奶牛能被前面牛看到的 ...

  6. HDU 6319(单调队列)

    传送门 题面: Problem A. Ascending Rating Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 524288/ ...

  7. 单调队列————[USACO09MAR]向右看齐Look Up

    先了解一下单调队列: 很明显的具有单调性 分为单调递增和单调递减两种,简单点讲就是维护队头为最大值或者为最小值 (建议采用双向队列  比较好写) 具体步骤:(这个是单调递减) 如果队列非空且当前值比队 ...

  8. 单调队列多重背包时间复杂度O(vn)

    版权声明:本文为博主原创文章,未经博主允许不得转载. 多重背包问题: 有N种物品和容量为V的背包,若第i种物品,容量为v[i],价值为w[i],共有n[i]件.怎样装才能使背包内的物品总价值最大? 网 ...

  9. 洛谷 P2219修筑绿化带 二维单调队列~

    题目链接:https://www.luogu.org/problem/P2219 emmm调了一个上午+中午,fan 题意:从N*M的中找到一个a*b的大矩形和减去a*b中的一个与之不重边界的c*d的 ...

  10. P2216 理想的正方形 单调队列 (二维)

    题目链接:https://www.luogu.org/problem/P2216 题意:求给定n*m的矩形中所有k*k的正方形块中最大值最小值之差(极差)最小 哇,大神的思路真的很帅 单调队列对每一行 ...

最新文章

  1. Jobs(三) HTML的form表单提交中文后,后台取出乱码的问题
  2. 芯片支持的且会被用到的H.264特性 预测编码基本原理
  3. java8获取当前时间并格式化
  4. ISE与Notepad++关联
  5. java编写万年历_怎么用JAVA编写万年历!
  6. 详解spring 每个jar的作用(转)
  7. node 版本管理器 之 nvm 安装与使用
  8. Java垃圾回收的工作原理和最佳做法
  9. 怎么查询网络热点事件的舆论热度的办法技巧
  10. Windows电脑微信多开方法
  11. android:layout_weight=1,Android:LinearLayout布局中Layout_weight的深刻理解
  12. 一篇文章,读懂品牌广告与效果广告的相同和不同
  13. MNIST 数据集分类
  14. 人民币贬值如何影响你的生活
  15. 数据库的基本概念-基础(课堂笔记)
  16. 欧盟非个人数据流动监管新进展
  17. 达立易考教育2023年全真模拟考试盛大开考,是骡子是马溜溜
  18. 查询海康、大华RTSP协议
  19. 噪声与振动控制行业的发展和展望
  20. A morphable model for the synthesis of 3D faces 学习笔记(未完)

热门文章

  1. 拓端tecdat|stata具有异方差误差的区间回归
  2. 拓端tecdat|R语言隐马尔可夫模型HMM识别不断变化的市场条件
  3. (10)数据分析-变量分析
  4. Linux下conda 安装以后 activate无法使用
  5. heidisql连接远程数据库_远程连接数据库异常问题
  6. 优质书籍资源仓库推荐【欢迎推送书籍】
  7. python '/'与'//'学习
  8. 三星手机怎么看html5,高端手机什么样?看三星S20 FE 5G就知道了
  9. JDK动态代理执行过程分析
  10. 以太坊 ERC-20 ERC-721 ERC-1155区别对比