【单调队列】POJ2823-Sliding Window
2015-07-20 22:01
344 查看
单调队列经典题之一。
【思路】
设置两个单调队列分别记录最大值和最小值。对于每一个新读入的数字,进行两次操作(对于求最大值和最小值中的某一个而言),一是若队首不在滑窗范围内则删去;二是删去队末比当前值小(或大)的值,并将当前值插入对尾。每一次的最小(大)值就是当前单调队列的队首。
【错误点】
一定要写while (scanf("%d%d",&n,&k)!=EOF),否则会WA。
我一开始的做法是这样的:先把第一个数插入队尾,再从第二个数开始进行后续操作。这样的问题在于如果滑窗大小为1,则第一个数无法被输出就出队,导致WA。故一定要先设置一个空队列,再逐一插入。
【思路】
设置两个单调队列分别记录最大值和最小值。对于每一个新读入的数字,进行两次操作(对于求最大值和最小值中的某一个而言),一是若队首不在滑窗范围内则删去;二是删去队末比当前值小(或大)的值,并将当前值插入对尾。每一次的最小(大)值就是当前单调队列的队首。
【错误点】
一定要写while (scanf("%d%d",&n,&k)!=EOF),否则会WA。
我一开始的做法是这样的:先把第一个数插入队尾,再从第二个数开始进行后续操作。这样的问题在于如果滑窗大小为1,则第一个数无法被输出就出队,导致WA。故一定要先设置一个空队列,再逐一插入。
#include<iostream> #include<cstdio> using namespace std; const int MAXN=1000000+10; int n,k,maxh,minh,maxt,mint; int maxq[MAXN],minq[MAXN],num[MAXN]; int maxans[MAXN],minans[MAXN]; int main() { while (scanf("%d%d",&n,&k)!=EOF) { int maxhead=0,minhead=0,maxtail=0,mintail=0; for (int i=0;i<n;i++) { /*删除下标超出范围的队首元素*/ if (maxhead<maxtail && maxq[maxhead]<=i-k) maxhead++; if (minhead<mintail && minq[minhead]<=i-k) minhead++; /*删除队尾元素*/ scanf("%d",&num[i]); while (maxhead<maxtail && num[maxq[maxtail-1]]<=num[i]) maxtail--;maxtail++; maxq[maxtail-1]=i; while (minhead<mintail && num[minq[mintail-1]]>=num[i]) mintail--;mintail++; minq[mintail-1]=i; maxans[i]=num[maxq[maxhead]]; minans[i]=num[minq[minhead]]; } for (int i=k-1;i<n;i++) cout<<minans[i]<<' ';cout<<endl; for (int i=k-1;i<n;i++) cout<<maxans[i]<<' ';cout<<endl; } return 0; }
相关文章推荐
- 【读书笔记】ARC-循环引用-解决办法
- leetcode 日经贴,Cpp code -Sliding Window Maximum
- Qt MVC学习 模型子类化参考(二)
- Linux设置系统语言
- Java回调函数的理解
- testng进行单元测试时报错Software caused connection abort: socket write error解决方法
- 1 Angular2 Set up
- android fragment学习总结
- Eclipse缺少字体解决办法
- hdu 1266 Reverse Number
- iOS:App启动过程详解
- 触摸控(触摸与移动 Touch & Mobility)的官方教程
- POJ3620
- extern "C"
- linux学习笔记1
- Hadoop+HBase+ZooKeeper分布式集群环境搭建
- Android混淆之ProGuard
- Hadoop+HBase+ZooKeeper分布式集群环境搭建
- HTML基础标签
- 一步一步学习多线程编程之线程同步通信