百度之星 2013 水果忍者

Problem

在二维平面中,有很多半径均为 R R R的圆,其中 y y y轴负方向为重力方向。

它们在 0 0 0时刻圆心坐标为 ( x i , y i ) (x_i,y_i) (xi,yi),且速度矢量为 v ⃗ i = ( v x i , v y i ) \vec v_i=(v_{xi},v_{yi}) v i=(vxi,vyi),做斜抛运动。

问在给定时间区间 [ 0 , E ] [0,E] [0,E]内,一条直线最多能同时穿过多少个圆?

n ≤ 100 ; R , E ≤ 1000 n\leq 100;R,E\leq 1000 n100;R,E1000

Solution

可以证明必然有一种最优情况下,这条直线和某两个圆相切,因为如果不满足该条件,那么可以通过先平移该直线直到和某个圆相切,再绕切点旋转的方法得到一条新的直线,且不使得穿过的圆的数量减少。

可以证明必然有一种最优情况下,该直线必定是两个圆的外公切线(即圆心在该公切线的同侧)。

注意到每个圆的半径都相等,那么外公切线其实和两圆圆心的连线是平行的。那么我们其实可以把该直线平移到与圆心连线平行,再将其他所有的圆的半径相应地增加R,问题依然等价,避免了求公切线的麻烦。问题转化为了求动点到动直线的距离。

我们可以考虑枚举两个圆,如果能求出第三个圆被该直线穿过的时间区间,那么就可以方便地按照时间DP即可求出最大覆盖,并更新答案。

考虑枚举了三个圆之后,如何求相应的时间区间。我们以第一个圆为参考系,这样就只需要考虑相对速度,圆变成了直线运动

x 1 ′ = v x 1 ′ t + x 1 , y 1 ′ = v y 1 ′ t + y 1 (1) x_1'=v_{x1}'t+x_1,y_1'=v_{y1}'t+y_1 \tag 1 x1=vx1t+x1,y1=vy1t+y1(1)

x 2 ′ = v x 2 ′ t + x 2 , y 2 ′ = v y 2 ′ t + y 2 (2) x_2'=v_{x2}'t+x_2,y_2'=v_{y2}'t+y_2 \tag 2 x2=vx2t+x2,y2=vy2t+y2(2)

动直线的方程:
y = k x = y 1 ′ x 1 ′ x (3) y=kx=\frac {y_1'} {x_1'}x \tag 3 y=kx=x1y1x(3)

则要解的方程为:
∣ y 2 ′ − k x 2 ′ ∣ k 2 + 1 ≤ 4 R 2 (4) \frac {|y_2'-kx_2'|} {\sqrt{k^2+1}}\leq 4R^2 \tag 4 k2+1 y2kx24R2(4)

联立 ( 1 ) ( 2 ) ( 3 ) ( 4 ) (1)(2)(3)(4) (1)(2)(3)(4)式,整理得:
( y 2 ′ x 1 ′ − y 1 ′ x 2 ′ ) 2 − 4 R 2 ( ( x 1 ′ ) 2 + ( y 1 ′ ) 2 ) ≤ 0 (5) (y_2'x_1'-y_1'x_2')^2-4R^2\biggl((x_1')^2+(y_1')^2\biggr)\leq 0 \tag 5 (y2x1y1x2)24R2((x1)2+(y1)2)0(5)

是一个关于 t t t的四次方程,使用牛顿迭代解之,判断区间用穿针引线法即可。

需要注意的是牛顿迭代不一定能解分式的根,故把分式全都去掉,整理出了 ( 5 ) (5) (5)式。另外需要注意在两边同乘分母的时候,乘的都是正数,故无需再讨论不等号方向。

理论时间复杂度 O ( n 3 ) O(n^3) O(n3),但解方程的复杂度略高导致常数很大。

Code

老年嘴巴选手不写代码

千万不要试图做防AK题,要折寿了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值