Window

来源:互联网 发布:苹果id解锁软件 编辑:程序博客网 时间:2024/06/10 15:56

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 31 3 -1 -3 5 3 6 7

Sample Output

-1 -3 -3 -3 3 33 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]);}
0 0
原创粉丝点击