整理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.
→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.
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.