样例
window.in
8 3
1 3 -1 -3 5 3 6 7
window.out
-1 -3 -3 -3 3 3
3 3 5 5 6 7
前面已经说了朴素能得30分,加上优化后能得100分
这里说说单调队列http://www.cnblogs.com/oijzh/articles/2647166.html
利用单调队列的单调性,每次入队,算最小的时候,只要当前最小的没出队,那么其他比它大的就根本不可能作为最小的输出,所以每次入队判断即可
算最大的同理
如果大家对单调队列理解不是很清楚,可以看看资料,或者看看代码,是这理解一下
单调队列 Pascal Code
program window;
var
n,k:longint;
a:array[0..1000000+10] of longint;
l,r:longint;
q:array[0..1000000+10] of longint;
procedure init;
begin
assign(input,'window.in');
assign(output,'window.out');
reset(input);
rewrite(output);
end;
procedure outit;
begin
close(input);
close(output);
halt;
end;
procedure readdata;
var
i:longint;
begin
read(n,k);
for i:=1 to n do read(a[i]);
end;
procedure main;
var
i:longint;
begin
fillchar(q,sizeof(q),0);l:=0;r:=0;
for i:=1 to n do
begin
if q[l+1]<i-k+1 then inc(l);
while (l<r)and(a[q[r]]>=a[i]) do dec(r);
inc(r);
q[r]:=i;
if i>=k then write(a[q[l+1]],' ');
end;
writeln;
fillchar(q,sizeof(q),0);l:=0;r:=0;
for i:=1 to n do
begin
if q[l+1]<i-k+1 then inc(l);
while (l<r)and(a[q[r]]<=a[i]) do dec(r);
inc(r);
q[r]:=i;
if i>=k then write(a[q[l+1]],' ');
end;
end;
begin
init;
readdata;
main;
outit;
end.
附上快排优化的思路和代码
先把数据快排一次,注意要处理处一个标号数组一起快排!!!
然后n个数,每个区间k个数,那么就会有n-k+1个区间,分别用1..n-k+1表示
求最小的时候,把队列从最小开始扫描一次,比如最小是-3 标号是2 ,那么就从2开始把往前的k个区间都填成-3,(注意:要先判断该区间是否填过,填过的不能再填,因为后面的不可能比前面的更优!!!判断可以用hash数组实现),在用一个计数器count,每填一个就+1,直到count=n-k+1的时候表示全部区间填完了,就马上退出当前这个计算模块。然后计算最大的同。
Pascal Code
program window;
var
n,k:longint;
a,nn,min,max:array[0..1000000+10] of longint;
h:array[0..1000000+10] of boolean;
num,maxnum:longint;
procedure init;
begin
assign(input,'window.in');
assign(output,'window.out');
reset(input);
rewrite(output);
end;
procedure outit;
begin
close(input);
close(output);
halt;
end;
procedure readdata;
var
i:longint;
begin
read(n,k);
for i:=1 to n do read(a[i]);
for i:=1 to n do nn[i]:=i;
end;
procedure qs(l,r:longint);
var
i,j,x,t:longint;
begin
i:=l;j:=r;x:=a[i+(j-i)div 2];
repeat
while a[i]>x do inc(i);
while a[j]<x do dec(j);
if i<=j then
begin
t:=a[i];a[i]:=a[j];a[j]:=t;
t:=nn[i];nn[i]:=nn[j];nn[j]:=t;
inc(i);dec(j);
end;
until i>j;
if i<r then qs(i,r);
if l<j then qs(l,j);
end;
procedure workmax;
var
i,j,t:longint;
begin
fillchar(h,sizeof(h),0);
maxnum:=n-k+1;
num:=0;
for i:=1 to n do
begin
t:=nn[i];
for j:=1 to k do
begin
if (t<1) then continue;
if (not h[t])and(t<=maxnum) then
begin
h[t]:=true;
max[t]:=a[i];
inc(num);
if num=maxnum then exit;
end;
dec(t);
end;
end;
end;
procedure workmin;
var
i,j,t:longint;
begin
fillchar(h,sizeof(h),0);
maxnum:=n-k+1;
num:=0;
for i:=n downto 1 do
begin
t:=nn[i];
for j:=1 to k do
begin
if t<1 then continue;
if (not h[t])and(t<=maxnum) then
begin
h[t]:=true;
min[t]:=a[i];
inc(num);
if num=maxnum then exit;
end;
dec(t);
end;
end;
end;
procedure main;
var
i,j,t:longint;
begin
qs(1,n);
//for i:=1 to n do write(a[i],' ');
//找最大
workmax;
//找最小
workmin;
for i:=1 to n-k+1 do write(min[i],' ');writeln;
for i:=1 to n-k+1 do write(max[i],' ');writeln;
end;
begin
init;
readdata;
main;
outit;
end.