您的位置:首页 > 其它

解题报告 最小波动

2011-11-09 17:24 169 查看
最小波动

最小波动是在一串数种出现的一种现象,给定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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: