2328: [HNOI2011]赛车游戏 - BZOJ

先把一定要减的费用先减掉,就是b*s*len(上坡路),下坡路就设一个初速度,使耗油为0,如果没油了,就无法到达

然后考虑加速

对于长度为len的路,增加v的速度需要len*a*v的油,与len成正比

然后又因为原来的速度越小,增加等量v的增益越高,所以每次都从最小的速度开始加(不超过第二小),还有不要超过vmax

  1 const
  2         maxn=10010;
  3 var
  4         t,n:longint;
  5         a,b,vmax,f:double;
  6         len,s,v:array[0..maxn]of double;
  7  
  8 procedure init;
  9 var
 10         i:longint;
 11         x,y:double;
 12 begin
 13         read(a,b,vmax,f,n);
 14         for i:=1 to n do
 15           begin
 16             read(x,y);
 17             len[i]:=sqrt(sqr(x)+sqr(y))/1000;
 18             s[i]:=y/x;
 19             if s[i]>0 then f:=f-len[i]*b*s[i];
 20             if s[i]<0 then v[i]:=-b*s[i]/a
 21             else v[i]:=0;
 22           end;
 23 end;
 24  
 25 procedure swap(var x,y:double);
 26 var
 27         t:double;
 28 begin
 29         t:=x;x:=y;y:=t;
 30 end;
 31  
 32 procedure sort(l,r:longint);
 33 var
 34         i,j:longint;
 35         y:double;
 36 begin
 37         i:=l;
 38         j:=r;
 39         y:=v[(l+r)>>1];
 40         repeat
 41           while v[i]<y do
 42             inc(i);
 43           while v[j]>y do
 44             dec(j);
 45           if i<=j then
 46           begin
 47             swap(s[i],s[j]);
 48             swap(v[i],v[j]);
 49             swap(len[i],len[j]);
 50             inc(i);
 51             dec(j);
 52           end;
 53         until i>j;
 54         if i<r then sort(i,r);
 55         if j>l then sort(l,j);
 56 end;
 57  
 58 procedure work;
 59 var
 60         i,j:longint;
 61         sum:double;
 62 begin
 63         sort(1,n);
 64         for i:=1 to n do
 65           if v[i]>vmax then v[i]:=vmax;
 66         v[n+1]:=vmax;
 67         sum:=0;
 68         for i:=1 to n do
 69           begin
 70             sum:=sum+len[i];
 71             if v[i]<>v[i+1] then
 72             begin
 73               if f>=(v[i+1]-v[i])*sum*a then
 74                 begin
 75                   f:=f-(v[i+1]-v[i])*sum*a;
 76                   v[i]:=v[i+1];
 77                 end
 78               else
 79                 begin
 80                   v[i]:=v[i]+f/(sum*a);
 81                   break;
 82                 end;
 83             end;
 84           end;
 85         for j:=i-1 downto 1 do
 86           v[j]:=v[j+1];
 87         if v[1]=0 then
 88         begin
 89           writeln('IMPOSSIBLE');
 90           exit;
 91         end;
 92         sum:=0;
 93         for i:=1 to n do
 94           sum:=sum+len[i]/v[i];
 95         writeln(sum:0:5);
 96 end;
 97  
 98 begin
 99         read(t);
100         while t>0 do
101           begin
102             init;
103             if f<0 then writeln('IMPOSSIBLE')
104             else work;
105             dec(t);
106           end;
107 end.
View Code

 

转载于:https://www.cnblogs.com/Randolph87/p/3667963.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值