【模拟试题】滑动窗口(BSOI2604)
2017-03-02 15:08
204 查看
【模拟试题】滑动窗口
Description
给你一个长度为N的数组,一个长为K的滑动的窗体从最左移至最右端,你只能见到窗口的K个数,每次窗体向右移动一位,如下图:你的任务是找出窗体在各位置时的最大值和最小值。
Input
第1行:2个整数N,K(K<=N<=1000000) 第2行:N个整数,表示数组的N个元素(<=2*10^9)
Output
第1行:滑动窗口从左向右移动每个位置的最小值,每个数之间用一个空格分开 第2行:滑动窗口从左向右移动每个位置的最大值,每个数之间用一个空格分开
Sample Input
8 31 3 -1 -3 5 3 6 7
Sample Output
-1 -3 -3 -3 3 33 3 5 5 6 7
Solution
单调队列模板。维护一个长度为k的单调队列,每次用队首来的出最大和最小值,新加入的数就放在队尾。
如果队首的距离大于k,则head++,即队首出队。若新来的数值比队尾更优,则tail--,即队尾出队。
CODE
#include<iostream> #include<cstdio> using namespace std; int n,k,a[1000005]; struct Queue{int val,pos;}q[1000005]; inline int read(){ char c;int rec=0,f=1; while((c=getchar())<'0'||c>'9')if(c=='-')f=-1; 4000 while(c>='0'&&c<='9')rec=rec*10+c-'0',c=getchar(); return rec*f; } void work(bool f) { int head=1,tail=0,i; for(i=1;i<k;i++) { if(f)while(a[i]<q[tail].val&&tail>0)tail--; else while(a[i]>q[tail].val&&tail>0)tail--; q[++tail].val=a[i];q[tail].pos=i; } for(i=k; i<=n; i++) { if(f)while(a[i]<q[tail].val&&tail>=head)tail--; else while(a[i]>q[tail].val&&head<=tail)tail--; q[++tail].val=a[i];q[tail].pos=i; while(q[head].pos+k<=i&&head<=tail)head++; cout<<q[head].val<<" "; }cout<<'\n'; return ; } int main() { n=read();k=read(); for(int i=1;i<=n;i++)a[i]=read(); work(1);work(0); return 0; }
相关文章推荐
- 复赛模拟试题 - 盛夏的果实 SPFA(队列优化)+二分答案法 重庆一中高2018级竞赛班第七次测试 2016.8.4 Problem 4
- 2016普级组模拟试题 给出字符串
- 会计电算化模拟试题9
- 【模拟试题】数列 矩阵快速幂
- 【模拟试题】逛公园
- 蓝桥杯 历届试题 分糖果 (模拟)
- 【模拟试题】技能树 树形DP
- 蓝桥杯历届试题 分糖果(简单模拟)
- 第二届国信蓝点模拟试题
- 【模拟试题】完成工作
- 【模拟试题2】【20150520】
- 【复赛模拟试题】书的排序
- 应网友要求,发几套软考网规(网络规划设计师)的模拟试题
- Red Hat Linux - RHCT部分模拟试题 //全部自己解答,如有疑问请纠正//
- 2010年3月三级网络技术 考前模拟试题
- Dreamweaver网页设计模拟试题 1
- 蓝桥杯 历届试题 分糖果 (模拟)
- 2016普级组模拟试题(20161114) 平台
- 网络数据库SQL模拟试题
- SQL Server 2000 数据库程序设计模拟试题