最小波动
最小波动是在一串数种出现的一种现象,给定n个数Ai,第i个数的最小波动k=min{|Aj-Ai|}(1=<j<i).而第一个数的最小波动为A1本身。
下面我们给定一串数,让你求出对于每个Ai的最小波动的和。
输入格式
第一行一个整数n(n<=200000),表明字串中数的个数。
接下来n行,每行一个整数Ai,(-32767=<Ai<=32767);
输出格式
一个数sum表示最小波动的和。
输入样例
6
5
1
2
5
4
6
输出格式
12
呃,这个题据说可以用 BST(平衡树),但是这个东西 NOIP 不考,对付这种水题又有一种杀鸡牛刀的感觉,所以,模贪(模拟+贪心)水过。
首先,挨个读入,与此同时,每读入一个 x ,v[x]:=true ,然后如果这个 x 不是第一项,就将它往两边找,一直到找到一个 true ,然后,取它们的abs 差值 ,加到 ans 上。
代码 (SueMiller)
program ACRush;
var v:array[-50000..50000]of boolean;
i,j,k,top,t1,t2,n,temp,min,max:longint;
ans:longint;
begin
assign(input,'min.in');reset(input);
assign(output,'min.out');rewrite(output);
readln(n);
fillchar(v,sizeof(v),false);
readln(temp);
ans:=temp;
v[temp]:=true;
max:=temp;
min:=temp;
for i:=2 to n do
begin
readln(temp);
if v[temp] then continue;
if temp>=max then
begin
inc(ans,temp-max);
v[temp]:=true;
max:=temp;
continue;
end;
if temp<=min then
begin
v[temp]:=true;
inc(ans,min-temp);
min:=temp;
continue;
end;
k:=temp;
j:=temp;
while (not v[k]) and (not v[j]) do
begin
if (k>max) and (j<min) then break;
if k<=max then inc(k);
if j>=min then dec(j);
end;
if v[k] then inc(ans,abs(k-temp))
else inc(ans,abs(j-temp));
v[temp]:=true;
end;
writeln(ans);
close(input);close(output);
end.