您的位置:首页 > 其它

Window

2016-07-08 07:18 239 查看

Window (Standard IO)

Time Limits: 1000 ms Memory Limits: 65536 KB

Description

  给你一个长度为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]);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: