滑动窗口_单调队列入门 (白书P241)
2015-09-03 16:42
363 查看
#include <iostream> #include <fstream> using namespace std; #define MAX 1000001 int A[MAX]; //存储数据 int Q[MAX]; //队列 int P[MAX]; //存储A[i]中的下标i int Min[MAX]; //输出最小 int Max[MAX]; //输出最大 int n,k; void get_min() { int i; int head=1,tail=0; for(i=0; i<k-1; i++) //先把前两个入队 { while(head<=tail && Q[tail]>=A[i]) //队尾元素大于要插入的数 --tail; Q[++tail]=A[i]; P[tail]=i; } for(; i<n; i++) { while(head<=tail && Q[tail]>=A[i]) --tail; Q[++tail]=A[i]; P[tail]=i; while(P[head]<i-k+1) //判断数是否过时,即窗口是否已经划过这个数,我这是从0开始计数的。 { head++; } Min[i-k+1]=Q[head]; } } void get_max() { int i; int head=1,tail=0; for(i=0; i<k-1; i++) { while(head<=tail && Q[tail]<=A[i]) //队尾元素小于要插入的值 --tail; Q[++tail]=A[i]; P[tail]=i; } for(; i<n; i++) { while(head<=tail && Q[tail]<=A[i]) //队尾元素小于要插入的值 --tail; Q[++tail]=A[i]; P[tail]=i; while(P[head]<i-k+1) { head++; } Max[i-k+1]=Q[head]; } } void output() { int i; //输出最下值 for(i=0; i<n-k+1; i++) { if(i==0) printf("%d",Min[i]); else printf(" %d",Min[i]); } printf("\n"); //输出最大值 for(i=0; i<n-k+1; i++) { if(i==0) printf("%d",Max[i]); else printf(" %d",Max[i]); } printf("\n"); } int main() { int i; // freopen("acm.txt","r",stdin); scanf("%d%d",&n,&k); for(i=0; i<n; i++) { scanf("%d",&A[i]); } get_min(); get_max(); output(); return 0; }
相关文章推荐
- 二分查找
- Matlab界面设计入门
- for 语句头中多个定义
- 替换空格
- 数据结构 1____概论
- PAT(B) 1021. 个位数统计(简单哈希)
- 使用极光推送自定义消息打造个性的消息推送效果
- C 结构体位域
- jQuery基础学习3——jQuery库冲突
- 关于C++中的友元函数的总结
- 基本数据类型与byte之间的相互转换
- HDU 2047 阿牛的EOF牛肉串 递推
- 【OpenCV第一篇】安装OpenCV
- Hello JSP!——JSP动作元素分类
- Open Data Plane (ODP) 源码下载(git 服务器搭建)
- iOS的block内存管理
- Linux I/O 进阶
- vim编辑器使用详解
- 华硕笔记本U盘启动设置
- java_对象(this和成员变量和Static修饰符)