首页 > 代码库 > BZOJ3190[JLOI2013]赛车
BZOJ3190[JLOI2013]赛车
Description
这里有一辆赛车比赛正在进行,赛场上一共有N辆车,分别称为个g1,g2……gn。赛道是一条无限长的直线。最初,gi位于距离起跑线前进ki的位置。比赛开始后,车辆gi将会以vi单位每秒的恒定速度行驶。在这个比赛过程中,如果一辆赛车曾经处于领跑位置的话(即没有其他的赛车跑在他的前面),这辆赛车最后就可以得奖,而且比赛过程中不用担心相撞的问题。现在给出所有赛车的起始位置和速度,你的任务就是算出那些赛车将会得奖。
Input
第一行有一个正整数N表示赛车的个数。
接下来一行给出N个整数,按顺序给出N辆赛车的起始位置。
再接下来一行给出N个整数,按顺序给出N辆赛车的恒定速度。
Output
输出包括两行,第一行为获奖的赛车个数。
第二行按从小到大的顺序输出获奖赛车的编号,编号之间用空格隔开,注意最后一个编号后面不要加空格。
Sample Input
4
1 1 0 0
15 16 10 20
1 1 0 0
15 16 10 20
Sample Output
3
1 2 4
1 2 4
HINT
对于100%的数据N<=10000, 0<=ki<=10^9, 0<=vi<=10^9
题解:
设位置为yi,yi=ki+ti*v,将其看作是y关于t的一次函数图像,毫无疑问,T时刻领先的赛车就是t=T时yi最大的函数。
这样,原题就变成了半平面交的模型,解法同BZOJ1007[HNOI2008]水平可见直线。
代码:
var i,j,l,r,n,m:longint; k,b,a,s:array[0..10001]of longint; v:array[0..10001]of boolean; flag:boolean; procedure sort(l,r:longint); var i,j,x,x2,y:longint; begin i:=l; j:=r; x:=k[(l+r)div 2]; x2:=b[(l+r)div 2]; repeat while(k[i]<x)or((k[i]=x)and(b[i]<x2))do inc(i); while(x<k[j])or((x=k[j])and(x2<b[j]))do dec(j); if i<=j then begin y:=k[i]; k[i]:=k[j]; k[j]:=y; y:=b[i]; b[i]:=b[j]; b[j]:=y; y:=a[i]; a[i]:=a[j]; a[j]:=y; inc(i); dec(j); end; until i>j; if i<r then sort(i,r); if j>l then sort(l,j); end; begin readln(n); for i:=1 to n do read(b[i]); for i:=1 to n do read(k[i]); for i:=1 to n do a[i]:=i; sort(1,n); r:=1; i:=1; while(i<n)and(k[i]=k[i+1])and(b[i]<>b[i+1])do inc(i); s[1]:=i; inc(i); k[0]:=-1; while i<=n do begin while(r>0)and(k[i]=k[s[r]])and(b[i]<>b[s[r]])do dec(r); if k[i]<>k[s[r]] then begin while(r>0)and((b[i]-b[s[r]])/(k[s[r]]-k[i])<0)do dec(r); while(r>1)and((b[i]-b[s[r]])/(k[s[r]]-k[i])< (b[s[r]]-b[s[r-1]])/(k[s[r-1]]-k[s[r]])) do dec(r); end; inc(r); s[r]:=i; inc(i); end; fillchar(v,sizeof(v),false); writeln(r); for i:=1 to r do v[a[s[i]]]:=true; flag:=false; for i:=1 to n do if v[i] then begin if not flag then begin flag:=true; write(i); end else write(‘ ‘,i); end; writeln; end.
BZOJ3190[JLOI2013]赛车
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。