Window
2016-07-08 07:18
239 查看
Window (Standard IO)
Time Limits: 1000 ms Memory Limits: 65536 KBDescription
给你一个长度为N的数组,一个长为K的滑动的窗体从最左移至最右端,你只能见到窗口的K个数,每次窗体向右移动一位,如下表:
你的任务是找出窗口在各位置时的max value,min value.
Input
第1行n,k,第2行为长度为n的数组
Output
2行,第1行每个位置的min value,第2行每个位置的max value
Sample Input
8 3 1 3 -1 -3 5 3 6 7
Sample Output
-1 -3 -3 -3 3 3 3 3 5 5 6 7
Hint
数据范围:
20% : n<=500; 50%: n<=100000;
100%: n<=1000000;
解题思路:
思路一:线段树,pascal编90,C++可以卡过#include<cstdio> #include<cstring> #define fo(i,x,y) for(int i=x;i<=y;i++) using namespace std; int max[3000000],min[3000000],inp[1000001],ans[1000001][2],n,k,x,y; void build(int,int,int); void ask(int,int,int,int,int,int); int maxx(int,int); int minn(int,int); int main() { memset(min,0x7f,sizeof(min)); scanf("%d%d",&n,&k); fo(i,1,n)scanf("%d",&inp[i]); build(1,1,n); fo(i,0,n-k) { ans[i+1][0]=0x7fffffff; ask(1,1,n,i+1,i+k,i+1); } fo(i,0,n-k)printf("%d ",ans[i+1][0]);printf("\n"); fo(i,0,n-k)printf("%d ",ans[i+1][1]); } int maxx(int p,int q) {return p>q?p:q;} int minn(int p,int q) {return p<q?p:q;} void build(int w,int h,int t) { if(h>t)return; if(h==t) { min[w]=max[w]=inp[h]; return; } int x=2*w,y=x+1,mid=(h+t)>>1; build(x,h,mid);build(y,mid+1,t); max[w]=maxx(max[x],max[y]); min[w]=minn(min[x],min[y]); } void ask(int w,int h,int t,int l,int r,int p) { if(h>t)return; if(h==l && r==t) { ans[p][0]=minn(ans[p][0],min[w]); ans[p][1]=maxx(ans[p][1],max[w]); return; } int x=w*2,y=x+1,mid=(h+t)>>1; if(r<=mid) { ask(x,h,mid,l,r,p); }else{ if(l>mid) { ask(y,mid+1,t,l,r,p); }else{ ask(x,h,mid,l,mid,p); ask(y,mid+1,t,mid+1,r,p); } } }
思路2,单调队列,无论用哪一种编译器都能对。
#include<cstdio> #include<cstring> #define fo(i,x,y) for(int i=x;i<=y;i++) using namespace std; int max[1000001],locma[1000001],min[1000001],locmi[1000001],ans[1000001],n,k,x,inp,hmi,hma,tmi,tma; int insert(int,int); int main() { memset(min,0x7f,sizeof(min)); scanf("%d%d",&n,&k); hmi=hma=1;tmi=tma=0; fo(i,1,n) { scanf("%d",&inp); x=insert(i,inp); if(i>k-1) { printf("%d ",x); ans[i]=max[hma]; } } printf("\n"); fo(i,0,n-k)printf("%d ",ans[i+k]); } int insert(int w,int num)/*存入队列*/ { while(hma<=tma && locma[hma]<=w-k)hma++;/*处理已经过期的元素*/ while(hma<=tma && max[tma]<num)tma--;/*处理起不了作用的元素,更新队列*/ max[++tma]=num;locma[tma]=w;/*存入队列*/ while(hmi<=tmi && locmi[hmi]<=w-k)hmi++; while(hmi<=tmi && min[tmi]>num)tmi--; min[++tmi]=num;locmi[tmi]=w; return(min[hmi]); }
相关文章推荐
- android studio ndk 环境搭建
- YL杯超级篮球赛
- 源码推荐(0708B):拼图游戏( 闲暇之余用swift写的100多行代码的小游戏 ),UICollectionView
- Android: 亲测解决模拟器启动慢的问题
- windows程序设计学习笔记-设备无关位图
- 职业素养与职业声誉——北漂18年(62)
- Eclipse开发Android程序如何在手机上运行
- PCL1.8.0,VS2013配置教程。
- Delete Volume 操作 - 每天5分钟玩转 OpenStack(57)
- Delete Volume 操作 - 每天5分钟玩转 OpenStack(57)
- 1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
- Delete Volume 操作 - 每天5分钟玩转 OpenStack(57)
- 第39课:spark streaming中direct kafka 内幕实现彻底解密
- 欢迎使用CSDN-markdown编辑器
- 浅谈图标布局
- java学习之六(IO流上篇)
- Mybatis属性和数据库表字段不一致处理
- 15.4 DS1302的硬件信息
- 15.3 实时时钟芯片DS1302介绍
- 15.2 单片机SPI通信接口