解题报告 最小波动

最小波动

最小波动是在一串数种出现的一种现象,给定n个数Ai,第i个数的最小波动k=min{|Aj-Ai|}(1=<j<i).而第一个数的最小波动为A1本身。

下面我们给定一串数,让你求出对于每个Ai的最小波动的和。

输入格式

第一行一个整数nn<=200000),表明字串中数的个数。

   接下来n行,每行一个整数Ai,(-32767=<Ai<=32767;

  输出格式

  一个数sum表示最小波动的和。

输入样例 

6

5

1

2

5

4

6

输出格式

12

 

 

呃,这个题据说可以用 BST(平衡树),但是这个东西 NOIP 不考,对付这种水题又有一种杀鸡牛刀的感觉,所以,模贪(模拟+贪心)水过。

首先,挨个读入,与此同时,每读入一个 v[x]:=true ,然后如果这个 不是第一项,就将它往两边找,一直到找到一个 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.

 

 

原文地址:https://www.cnblogs.com/SueMiller/p/2243315.html