解题报告 赛车

No.2赛车

     Maxingc不仅为暖熊买来了赛车,还为他买来了赛道,赛道的长度为L(2<=L<=10^9)m。赛车在起点的速度是1m/s,但是赛车的速度是可以改变的,每一米的速度可以是前一秒的速度加1,减1或不变。赛道有n(1<=n<=100 000)个转弯处,第i个转弯处位于距离出发点Ti(1<=Ti<=L-1)米处,为了安全起见,赛车到达第i个转弯处的速度不能超过Si(1<=Si<=10^9)米每秒,当然赛车到达终点时的速度没有最大的限度。

     Maxingc让暖熊1秒内计算出赛车能达到的最大的速度是多少,否则就不让他吃晚饭。

 这这这……为了暖熊的人身安全,还是请教你吧!

   输入格式:

         第一行:两个正整数L,N。

         第二行到第N+1行:第i+1行描述的是第i个转弯处的两个参数Ti,Si。

   输出格式:

        一个整数,表示赛车能达到的最大速度(包括起点和终点的速度)。

   输入样例:

       14 3

        7 3

        11 1

        13 8

   输出样例:

       5

样例说明:

限速

             

3

     

1

 

8

 

距离

0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

速度

1

2

3

4

5

5

4

3

4

3

2

1

2

3

4

 

 

首先,输入数据不一定是有序的,所以要排序。。。。。。(maxingc 我要把你……&*&……%%*

 

然后,分析一种情况,那个所谓的 s[i] 并一定不是可以达到的最大速度,可以达到的最大速度还要保证,这个速度可以由上一个转弯的最大速度加速而来,并可以成功的减速到下一个转弯处。

 

然后,在两个转弯之间,让这个车的速度先升再降,用这两个转弯之间的距离减去调整两个转弯之间的速度差的距离,然后剩下的距离让这个车一半加速,一半减速,找出中间那个最大距离。

 

代码 maxingc

var

  i,j,k,n,m,l:longint;

  t,s:array[0..100001] of longint;

  aa,bb,ans,tmp:longint;

 

procedure init;

  begin

    readln(l,n);

    for i:=1 to n do

      read(t[i],s[i]);

  end;

function min(a,b:longint):longint;

  begin

    if a<b then exit(a)

      else exit(b);

  end;

 

procedure fast(l,r:longint);

  var

    i,j,tt,tmp:longint;

  begin

    i:=l;

    j:=r;

    tt:=t[random(r-l+1)+l];

    repeat

      while t[i]<tt do inc(i);

      while t[j]>tt do dec(j);

      if i<=j then

        begin

          tmp:=t[i];t[i]:=t[j];t[j]:=tmp;

          tmp:=s[i];s[i]:=s[j];s[j]:=tmp;

          inc(i);dec(j);

        end;

      until i>j;

    if i<r then fast(i,r);

    if l<j then fast(l,j);

  end;

 

procedure main;

  begin

    fast(1,n);

    s[0]:=1;

    t[0]:=0;

    for i:=1 to n do

      s[i]:=min(s[i],s[i-1]+t[i]-t[i-1]);

    for i:=n-1 downto 1 do

      s[i]:=min(s[i],s[i+1]+t[i+1]-t[i]);  //话说,这是调整可以达到的最大速度。

 

    for i:=1 to n do

      begin

        if s[i-1]>s[i] then begin aa:=s[i-1];bb:=s[i] end

          else begin aa:=s[i];bb:=s[i-1]; end;

        tmp:=aa+(t[i]-t[i-1]-1-(aa-bb-1)) div 2;

        if tmp>ans then ans:=tmp;

      end;

    if s[n]+l-t[n]>ans then ans:=s[n]+l-t[n];

    writeln(ans);

  end;

 

begin

  assign(input,'bobsled.in');reset(input);

  assign(output,'bobsled.out');rewrite(output);

  randomize;  //普通 KP 也可以过,不用随机 KP 

  init;

  main;

  close(input);

  close(output);

end.

 

 

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