Window_纪中1326_水_单调队列

来源:互联网 发布:淘宝手游交易平台官网 编辑:程序博客网 时间:2024/05/22 17:31

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;

思路

原本想着是显而易见的线段树查找最大值,结果爆内存/(ㄒoㄒ)/~~
pige优美的暴力ac后才发现是水题
能暴力就暴力,做对那些脑残题
真理

方法I:

每次判断当前框里的最大值和最小值是否出了框,没有出框就与最大值和最小值比较,若出框了就在框里寻找最大值和最小值

方法II:

经大神指导后习得单调队列做法,然而Pascal TLE
于是乎我就手鲁出c++来
根据单调队列的性质我们可以很方便地求出最大值与最小值,注意查询是否出框

代码/pas

var  n,m,max,min,i,j:Longint;  a,t,r:array[0..1000000]of longint;  max_s,min_s:longint;function findmax(x:longint):longint;var  i:Longint;begin  findmax:=-maxlongint;  for i:=x to x+m-1 do  if findmax<a[i] then  begin    findmax:=a[i];    max_s:=i;  end;end;function findmin(x:Longint):Longint;var  i:longint;begin  findmin:=maxlongint;  for i:=x to x+m-1 do  if findmin>a[i] then  begin    findmin:=a[i];    min_s:=i;  end;end;begin  readln(n,m);  for i:=1 to n do  read(a[i]);  max:=findmax(1);  min:=findmin(1);  inc(t[0]);  t[t[0]]:=min;  r[t[0]]:=max;  for i:=2 to n-m+1 do  begin    if max_s>=i then    begin      if a[i+m-1]>max then      begin        max:=a[i+m-1];        max_s:=i+m-1;      end;    end    else    max:=findmax(i);    if min_s>=i then    begin      if a[i+m-1]<min then      begin        min:=a[i+m-1];        min_s:=i+m-1;      end;    end    else    min:=findmin(i);    inc(t[0]);    t[t[0]]:=min;    r[t[0]]:=max;  end;  for i:=1 to t[0] do  write(t[i],' ');  writeln;  for i:=1 to t[0] do  write(r[i],' ');end.

代码/c++

#include <stdio.h>struct rec{    int x,r;};rec t[1000000]={0};rec r[1000000]={0};int a[1000000]={0};int mx[1000000]={0};int mn[1000000]={0};int maxint=0xffffffff;int main(){    int n,m;    scanf("%d%d",&n,&m);    for (int i=1;i<=n;i++)        scanf("%d",&a[i]);    int p=0;    int q=0;    for (int i=1;i<=n;i++)    {        t[i].x=-maxint;        r[i].x=maxint;    }    for (int i=1;i<=n;i++)    {        t[++p].x=a[i];        t[p].r=i;        while (p>1&&t[p].x>t[p-1].x) t[p-1]=t[p--];        while (p>1&&t[p].r-t[1].r>=m)        {            int v=2;            while (v<p) t[v-1]=t[v++];            p--;        }        r[++q].x=a[i];        r[q].r=i;        while (q>1&&r[q].x<r[q-1].x) r[q-1]=r[q--];        while (q>1&&r[q].r-r[1].r>=m)        {            int v=2;            while (v<q) r[v-1]=r[v++];            q--;        }        mx[i]=t[1].x;        mn[i]=r[1].x;    }    for (int i=m;i<=n;i++) printf("%d ",mn[i]);    printf("\n");    for (int i=m;i<=n;i++) printf("%d ",mx[i]);    return 0;}
1 3
原创粉丝点击