• POJ 2823


    POJ 2823 Sliding Windows

    题目大意:给出一个长度为n的数组(1<=n<=10^6),然后

    For I := 1 to n-k+1 do 问区间a[I,i+k-1]内的最大最小值。

    解法:复杂度最高去到n^2,显然不能朴素询问,用单调队列去维护即可,用min举例,如果新+入的数比队尾大,则保留(以后可能会用到),若小,则不断dec(mint),直到比队尾大为止(为什么?其实就是一个贪心,新数进入窗口,说明数在窗口期间都是有效的,前面几个比它大的已经不用保存了,是一种贪心的思想),我是用了一个time数组来处理一个数是否在窗口内,比较麻烦,不知道是否有更好的方法了。

    {提出一个nlogn的算法,快排一下从第一个开始更新区间}

    View Code
     1 //poj p2823
    2 //orz fjy, this story from the way to gdoi2011
    3 const
    4 maxn=1000000;
    5 var
    6 a, qmin, qmax: array[1..maxn]of longint;
    7 mint, maxt, minh, maxh, n, k, tot: longint;
    8 pr, time: array[1..2, 1..maxn]of longint;
    9 procedure min(x, timing: longint);
    10 begin
    11 if x>qmin[mint] then inc(mint)
    12 else
    13 begin
    14 inc(mint);
    15 while (mint>minh)and(x<=qmin[mint-1]) do dec(mint);
    16 end;
    17 qmin[mint] := x;
    18 time[1, mint] := timing;
    19 end;
    20
    21 procedure max(x, timing: longint);
    22 begin
    23 if x<qmax[maxt] then inc(maxt)
    24 else
    25 begin
    26 inc(maxt);
    27 while (maxt>maxh)and(x>=qmax[maxt-1]) do dec(maxt);
    28 end;
    29 qmax[maxt] := x;
    30 time[2, maxt] := timing;
    31 end;
    32
    33 procedure init;
    34 var
    35 i: longint;
    36 begin
    37 fillchar(time ,sizeof(time), 0);
    38 minh := 1;
    39 mint := 1;
    40 maxh := 1;
    41 maxt := 1;
    42
    43 readln(n, k);
    44 for i := 1 to n do read(a[i]); readln;
    45 qmin[1] := a[1];
    46 qmax[1] := a[1];
    47 for i := 2 to k do
    48 begin
    49 min(a[i], i);
    50 max(a[i], i);
    51 end;
    52 tot := 1;
    53 pr[1, 1] := qmin[minh];
    54 pr[2, 1] := qmax[maxh];
    55 end;
    56
    57 procedure main;
    58 var
    59 i, j: longint;
    60 begin
    61 for i := k+1 to n do
    62 begin
    63 inc(tot);
    64 min(a[i], i);
    65 max(a[i], i);
    66 while (i-time[1, minh]>=k) do inc(minh);
    67 while (i-time[2, maxh]>=k) do inc(maxh);
    68 pr[1, tot] := qmin[minh];
    69 pr[2, tot] := qmax[maxh];
    70 end;
    71 end;
    72
    73 procedure print;
    74 var
    75 i, j: longint;
    76 begin
    77 for j := 1 to 2 do
    78 begin
    79 for i := 1 to tot do
    80 begin
    81 if i<>1 then write(' ');
    82 write(pr[j, i]);
    83 end;
    84 writeln;
    85 end;
    86 end;
    87
    88 begin
    89 {assign(input,'test.in'); reset(input);
    90 assign(output,'test.out'); rewrite(output); }
    91 init;
    92 main;
    93 print;
    94 //close(input);
    95 end.



  • 相关阅读:
    AOP静态代理解析2-代码织入
    算法笔记_064:蓝桥杯练习 操作格子(Java)
    算法笔记_063:蓝桥杯练习 送分啦(Java)
    算法笔记_062:蓝桥杯练习 最小乘积(基本型)(Java)
    算法笔记_061:蓝桥杯练习 字串统计(Java)
    算法笔记_060:蓝桥杯练习 出现次数最多的整数(Java)
    算法笔记_059:蓝桥杯练习 Anagrams问题(Java)
    算法笔记_058:蓝桥杯练习 2的次幂表示(Java)
    算法笔记_057:蓝桥杯练习 最大的算式 (Java)
    算法笔记_056:蓝桥杯练习 未名湖边的烦恼(Java)
  • 原文地址:https://www.cnblogs.com/wmzisfoolish/p/2435140.html
Copyright © 2020-2023  润新知