• [POJ2823]Sliding Window


      题目链接:2823 - Sliding Window

      整理POJ的程序发现了Sliding Window这道题,结果发现自己写过两种不同的解法。(非常滋磁POJ的Archive√)

    →Solution 1:

      由于这道题要求的是一个区间的最大最小值,我们就可以转化成RMQ来求。当时是用ST算法计算移动的区间的最大最小值。

     1 program p2823;
     2   var
     3     n,m,i,j,x,y,k:longint;
     4     dp,dp2,num:array[1..1000000]of longint;
     5   function log2(n:longint):longint;
     6     begin
     7       exit(trunc(ln(n)/ln(2)));
     8     end;
     9   function exp(n:longint):longint;
    10     begin
    11       exit(1 shl n);
    12     end;
    13   function max(n,m:longint):longint;
    14     begin
    15       if n>m then
    16         exit(n)
    17       else
    18         exit(m);
    19     end;
    20   function min(n,m:longint):longint;
    21     begin
    22       exit(n+m-max(n,m));
    23     end;
    24   begin
    25     read(n,m);
    26     k:=log2(m);
    27     for i:=1 to n do
    28       begin
    29         read(num[i]);
    30       end;
    31     dp:=num;
    32     for j:=1 to k do
    33       begin
    34         for i:=1 to n-exp(j)+1 do
    35           begin
    36             if i+exp(j-1)>n then
    37               continue;
    38             dp2[i]:=min(dp[i],dp[i+exp(j-1)]);
    39           end;
    40         dp:=dp2;
    41       end;
    42     for i:=1 to n-m+1 do
    43       begin
    44         x:=i;
    45         y:=i+m-1;
    46         k:=log2(y-x+1);
    47         write(min(dp[x],dp[y-exp(k)+1]),' ');
    48       end;
    49     writeln;
    50     dp:=num;
    51     for j:=1 to k do
    52       begin
    53         for i:=1 to n-exp(j)+1 do
    54           begin
    55             if i+exp(j-1)>n then
    56               continue;
    57             dp2[i]:=max(dp[i],dp[i+exp(j-1)]);
    58           end;
    59         dp:=dp2;
    60       end;
    61     for i:=1 to n-m+1 do
    62       begin
    63         x:=i;
    64         y:=i+m-1;
    65         k:=log2(y-x+1);
    66         write(max(dp[x],dp[y-exp(k)+1]),' ');
    67       end;
    68     writeln;
    69   end.
    View Code

    →Solution 2:

      我们还可以利用优先队列来求一个滑动的区间的最大最小值。

     1 program window;
     2   var
     3     n,k,i,j,hu,eu,hd,ed:longint;
     4     m,squ,sqd:array[0..1000000]of longint;
     5   begin
     6     read(n,k);
     7     hu:=1;
     8     eu:=1;
     9     hd:=1;
    10     ed:=1;
    11     squ[1]:=maxlongint;
    12     sqd[1]:=-maxlongint;
    13     for i:=1 to n do
    14       read(m[i]);
    15     for i:=1 to n do
    16       begin
    17         inc(eu);
    18         while (m[i]<squ[eu-1]) and (hu<eu) do
    19           dec(eu);
    20         squ[eu]:=m[i];
    21         if i-k>0 then
    22           if squ[hu]=m[i-k] then
    23             inc(hu);
    24         if i>=k then
    25           write(squ[hu],' ');
    26       end;
    27     writeln;
    28     for i:=1 to n do
    29       begin
    30         inc(ed);
    31         while (m[i]>sqd[ed-1]) and (hd<ed) do
    32           dec(ed);
    33         sqd[ed]:=m[i];
    34         if i-k>0 then
    35           if sqd[hd]=m[i-k] then
    36             inc(hd);
    37         if i>=k then
    38           write(sqd[hd],' ');
    39       end;
    40     writeln;
    41   end.
    View Code
     1 program sliding;
     2   var
     3     num,p,q:array [1..1000000] of longint;
     4     n,k,i,l,r:longint;
     5   begin
     6     read(n,k);
     7     for i:=1 to n do
     8       read(num[i]);
     9     l:=1;
    10     r:=0;
    11     for i:=1 to n do
    12       begin
    13         inc(r);
    14         while (r>l) and (q[r-1]>num[i]) do
    15           dec(r);
    16         q[r]:=num[i];
    17         p[r]:=i;
    18         if (p[l]<=i-k) then
    19           inc(l);
    20         if i>=k then
    21           write(q[l],' ');
    22       end;
    23     writeln;
    24     l:=1;
    25     r:=0;
    26     for i:=1 to n do
    27       begin
    28         inc(r);
    29         while (r>l) and (q[r-1]<num[i]) do
    30           dec(r);
    31         q[r]:=num[i];
    32         p[r]:=i;
    33         if (p[l]<=i-k) then
    34           inc(l);
    35         if i>=k then
    36           write(q[l],' ');
    37       end;
    38     writeln;
    39   end.
    View Code
  • 相关阅读:
    Ubuntu16.04+GTX2070+Driver418.43+CUDA10.1+cuDNN7.6
    N皇后问题
    Linux Bash之通配符
    Linux Bash之正则表达式
    Linux Bash文本操作之grep篇
    Linux Bash文本操作之sed篇其二
    Integer对象两种创建方式的比较
    Class文件版本号
    group by、group_concat()、if()
    字节码命令与Java语言在语义描述能力上的差异
  • 原文地址:https://www.cnblogs.com/Snak3s/p/5185968.html
Copyright © 2020-2023  润新知