【USACO Open 2012银】跑步Running laps (jzoj第四题)(变态)

59 篇文章 0 订阅
2 篇文章 0 订阅

题目:

题目描述

FJ觉得赛马很无聊,于是决定调查将赛牛作为一种运动的可能性。他安排了N(1 <= N <= 100,000)头奶牛来进行一个L圈的赛牛比赛,比赛在一个环形的长度为C的跑道上进行。所有的奶牛在跑道上的同一个点出发,每头奶牛的速度不同,当最快的奶牛跑完L*C的距离后结束。

FJ注意到了一头奶牛超过另一头奶牛这种情况的发生,并且他想知道这种“超车事件”在整个比赛中发生了多少次。更明确地,一次超车事件被定义为一对奶牛(x, y)和一个时刻t(小于等于结束时刻),且t时刻奶牛x超越到了奶牛y的前面,请帮助FJ计算整个比赛过程中“超车事件”发生的次数。

输入

第1行,3个空格隔开的整数N、L、C(1 <= L,C <= 25,000)

第2行至第n + 1行,第i + 1行有一个整数,表示第i个奶牛的速度,范围在1..1000000之间

输出

超车总数

样例输入

4 2 100

20

100

70

1

样例输出

4

作者思路:先把速度排序,求出比赛时间,然后求答案。用t[i]表示剩下时间,s[i]表示超过圈数。注意还要处理小数。

代码:

var t,t1:array[0..100001] of extended;
    v,s:array[0..100001] of int64;
    fuck,n,l,c,sum,ans:int64;
    i:longint;
    max:extended;

procedure qsort(l,r:longint);//快排
var i,j,mid:longint;
begin
  if l>=r then exit;
  i:=l; j:=r; mid:=v[i];
  repeat
    while v[i]>mid do inc(i);
    while v[j]<mid do dec(j);
    if i<=j then
      begin
        v[0]:=v[i];
        v[i]:=v[j];
        v[j]:=v[0];
        inc(i);
        dec(j);
      end;
  until i>j;
  qsort(l,j);
  qsort(i,r);
end;
procedure megen(x,y:longint);//归并
var mid,i,j,k:longint;
begin
  if x=y then exit;
  mid:=(x+y) div 2;
  megen(x,mid); megen(mid+1,y);
  i:=x; j:=mid+1;
  k:=x;
  while (i<=mid)and(j<=y) do
    if t[i]-t[j]>-0.0000001 then
    begin
      t1[k]:=t[i];
      inc(i); inc(k);
    end else
    begin
      t1[k]:=t[j];
      inc(j); inc(k);
      fuck:=fuck+mid-i+1;
    end;
  while (i<=mid) do
  begin
    t1[k]:=t[i];
    inc(i); inc(k);
  end;
  while j<=y do
  begin
    t1[k]:=t[j];
    inc(j);
    inc(k);
  end;

  for i:=x to y do t[i]:=t1[i];
end;
begin
  {assign(input,'running.in');
  assign(output,'running.out');
  reset(input);
  rewrite(output);      }

  read(n,l,c);
  for i:=1 to n do read(v[i]);
  qsort(1,n);
  max:=l*c/v[1];//比赛时间
  for i:=1 to n do
  begin
    s[i]:=trunc(v[i]*max/c);
    l:=s[i]*c;
    t[i]:=v[i]*max-l;
  end;
  for i:=n downto 1 do
  begin
    sum:=sum+(n-i)*(s[i]-s[i+1]);
    ans:=ans+sum;
  end;
  megen(1,n);
  write(ans-fuck);
  close(input);
  close(output);

end.//谢谢祝子扬的指导
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值