解题报告 赛车
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.