[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

 

你可能感兴趣的:([POJ2823]Sliding Window)