Description
给你一个长度为N的数组,一个长为K的滑动的窗体从最左移至最右端,你只能见到窗口的K个数,每次窗体向右移动一位,如下表:
你的任务是找出窗口在各位置时的max value,min value.
Input
第1行n,k,第2行为长度为n的数组
Output
2行,第1行每个位置的min value,第2行每个位置的max value
Sample Input
8 3
1 3 -1 -3 5 3 6 7
Sample Output
-1 -3 -3 -3 3 3
3 3 5 5 6 7
Hint
数据范围:
20%: n<=500; 50%: n<=100000;
100%: n<=1000000;
思路
原本想着是显而易见的线段树查找最大值,结果爆内存/(ㄒoㄒ)/~~
pige优美的暴力ac后才发现是水题
能暴力就暴力,做对那些脑残题
真理
方法I:
每次判断当前框里的最大值和最小值是否出了框,没有出框就与最大值和最小值比较,若出框了就在框里寻找最大值和最小值
方法II:
经大神指导后习得单调队列做法,然而Pascal TLE
于是乎我就手鲁出c++来
根据单调队列的性质我们可以很方便地求出最大值与最小值,注意查询是否出框
代码/pas
var
n,m,max,min,i,j:Longint;
a,t,r:array[0..1000000]of longint;
max_s,min_s:longint;
function findmax(x:longint):longint;
var
i:Longint;
begin
findmax:=-maxlongint;
for i:=x to x+m-1 do
if findmax<a[i] then
begin
findmax:=a[i];
max_s:=i;
end;
end;
function findmin(x:Longint):Longint;
var
i:longint;
begin
findmin:=maxlongint;
for i:=x to x+m-1 do
if findmin>a[i] then
begin
findmin:=a[i];
min_s:=i;
end;
end;
begin
readln(n,m);
for i:=1 to n do
read(a[i]);
max:=findmax(1);
min:=findmin(1);
inc(t[0]);
t[t[0]]:=min;
r[t[0]]:=max;
for i:=2 to n-m+1 do
begin
if max_s>=i then
begin
if a[i+m-1]>max then
begin
max:=a[i+m-1];
max_s:=i+m-1;
end;
end
else
max:=findmax(i);
if min_s>=i then
begin
if a[i+m-1]<min then
begin
min:=a[i+m-1];
min_s:=i+m-1;
end;
end
else
min:=findmin(i);
inc(t[0]);
t[t[0]]:=min;
r[t[0]]:=max;
end;
for i:=1 to t[0] do
write(t[i],' ');
writeln;
for i:=1 to t[0] do
write(r[i],' ');
end.
代码/c++
#include <stdio.h>
struct rec
{
int x,r;
};
rec t[1000000]={0};
rec r[1000000]={0};
int a[1000000]={0};
int mx[1000000]={0};
int mn[1000000]={0};
int maxint=0xffffffff;
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
int p=0;
int q=0;
for (int i=1;i<=n;i++)
{
t[i].x=-maxint;
r[i].x=maxint;
}
for (int i=1;i<=n;i++)
{
t[++p].x=a[i];
t[p].r=i;
while (p>1&&t[p].x>t[p-1].x) t[p-1]=t[p--];
while (p>1&&t[p].r-t[1].r>=m)
{
int v=2;
while (v<p) t[v-1]=t[v++];
p--;
}
r[++q].x=a[i];
r[q].r=i;
while (q>1&&r[q].x<r[q-1].x) r[q-1]=r[q--];
while (q>1&&r[q].r-r[1].r>=m)
{
int v=2;
while (v<q) r[v-1]=r[v++];
q--;
}
mx[i]=t[1].x;
mn[i]=r[1].x;
}
for (int i=m;i<=n;i++) printf("%d ",mn[i]);
printf("\n");
for (int i=m;i<=n;i++) printf("%d ",mx[i]);
return 0;
}