• 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

    Sample Output

    3
    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]水平可见直线。

    代码:

     1 var
     2   i,j,l,r,n,m:longint;
     3   k,b,a,s:array[0..10001]of longint;
     4   v:array[0..10001]of boolean;
     5   flag:boolean;
     6 procedure sort(l,r:longint);
     7 var
     8   i,j,x,x2,y:longint;
     9 begin
    10   i:=l; j:=r; x:=k[(l+r)div 2]; x2:=b[(l+r)div 2];
    11   repeat
    12     while(k[i]<x)or((k[i]=x)and(b[i]<x2))do inc(i);
    13     while(x<k[j])or((x=k[j])and(x2<b[j]))do dec(j);
    14     if i<=j then
    15     begin
    16       y:=k[i]; k[i]:=k[j]; k[j]:=y;
    17       y:=b[i]; b[i]:=b[j]; b[j]:=y;
    18       y:=a[i]; a[i]:=a[j]; a[j]:=y;
    19       inc(i); dec(j);
    20     end;
    21   until i>j;
    22   if i<r then sort(i,r);
    23   if j>l then sort(l,j);
    24 end;
    25 begin
    26   readln(n);
    27   for i:=1 to n do read(b[i]);
    28   for i:=1 to n do read(k[i]);
    29   for i:=1 to n do a[i]:=i;
    30   sort(1,n);
    31   r:=1; i:=1;
    32   while(i<n)and(k[i]=k[i+1])and(b[i]<>b[i+1])do inc(i);
    33   s[1]:=i; inc(i); k[0]:=-1;
    34   while i<=n do
    35   begin
    36     while(r>0)and(k[i]=k[s[r]])and(b[i]<>b[s[r]])do dec(r);
    37     if k[i]<>k[s[r]] then
    38     begin
    39       while(r>0)and((b[i]-b[s[r]])/(k[s[r]]-k[i])<0)do dec(r);
    40       while(r>1)and((b[i]-b[s[r]])/(k[s[r]]-k[i])<
    41       (b[s[r]]-b[s[r-1]])/(k[s[r-1]]-k[s[r]])) do dec(r);
    42     end;
    43     inc(r); s[r]:=i; inc(i);
    44   end;
    45   fillchar(v,sizeof(v),false);
    46   writeln(r);
    47   for i:=1 to r do v[a[s[i]]]:=true;
    48   flag:=false;
    49   for i:=1 to n do
    50   if v[i] then
    51   begin
    52     if not flag then
    53     begin
    54       flag:=true; write(i);
    55     end else write(' ',i);
    56   end;
    57   writeln;
    58 end.
    View Code
  • 相关阅读:
    使用 RetroShare 分享资源
    C# 代码占用的空间
    C# 代码占用的空间
    PHP date_timezone_set() 函数
    PHP date_timezone_get() 函数
    PHP date_timestamp_set() 函数
    PHP date_timestamp_get() 函数
    PHP date_time_set() 函数
    MHA软件下载地址
    [ZJOI2019]线段树
  • 原文地址:https://www.cnblogs.com/GhostReach/p/6262478.html
Copyright © 2020-2023  润新知