题目大意
给你一个度为N的数组,一个长为K的滑动的窗体从最左移至最右端,你只能见到窗口的K个数,每次窗体向右移动一位,如下表:
你的任务是找出窗口在各位置时的max value,min value.
分析
水法见——水法
还可以用单调队列。
单调队列见——单调队列
但是都要卡时间,pascal的问题
代码
var
a:array[0..1000001] of longint;
d,v:array[0..1000001] of longint;
head,tail:longint;
i,j,k:longint;
n,m:longint;
begin
readln(n,m);
for i:=1 to n do
read(a[i]);
head:=1;
tail:=1;
d[1]:=a[1];
v[1]:=1;
for i:=2 to m do
begin
while (d[tail]>a[i]) and (head<=tail) do
tail:=tail-1;
tail:=tail+1;
d[tail]:=a[i];
v[tail]:=i;
end;
write(d[1],' ');
for i:=m+1 to n do
begin
while (v[head]<=i-m) and (head<=tail) do
head:=head+1;
if tail<head then tail:=head;
while (d[tail]>a[i]) and (head<=tail) do
tail:=tail-1;
tail:=tail+1;
d[tail]:=a[i];
v[tail]:=i;
write(d[head],' ');
end;
writeln;
fillchar(d,sizeof(d),0);
fillchar(v,sizeof(v),0);
head:=1;
tail:=1;
d[1]:=a[1];
v[1]:=1;
for i:=2 to m do
begin
while (d[tail]<a[i]) and (head<=tail) do
tail:=tail-1;
tail:=tail+1;
d[tail]:=a[i];
v[tail]:=i;
end;
write(d[1],' ');
for i:=m+1 to n do
begin
while (v[head]<=i-m) and (head<=tail) do
head:=head+1;
if tail<head then tail:=head;
while (d[tail]<a[i]) and (head<=tail) do
tail:=tail-1;
tail:=tail+1;
d[tail]:=a[i];
v[tail]:=i;
write(d[head],' ');
end;
end.