#P17559. PM2887 林中奔跑

PM2887 林中奔跑

题目描述

树林中心位于坐标原点 (0,0)(0,0)。一只狗从给定位置出发,并按照下面的规则运动。

当狗没有接触树木时,它会以树林中心为圆心,沿当前半径对应的圆顺时针奔跑。如果它撞到一棵树,就改为沿这棵树的圆周逆时针奔跑,直到能够在更靠近树林中心的位置重新沿以原点为圆心的圆顺时针运动。

每棵树都是一个精确的圆盘,由圆心坐标 (xi,yi)(x_i,y_i) 和直径 did_i 给出。狗被视为一个没有大小的点,不能穿过树的内部。

当狗到树林中心的距离不超过 1010 时,认为它已经到达目的地并立即停止。请计算狗在停止前一共跑过的距离。

如果狗会永远按照上述规则奔跑而无法到达距离原点不超过 1010 的区域,输出 -1

几何补充

设一棵树的圆心为 (x0,y0)(x_0,y_0),半径为 r0r_0;当前以原点为圆心的运动圆半径为 r1r_1。两圆方程为

(xx0)2+(yy0)2=r02,(x-x_0)^2+(y-y_0)^2=r_0^2, x2+y2=r12.x^2+y^2=r_1^2.

D=x02+y02D=x_0^2+y_0^2,以及

$$p=\sqrt{\big((r_0+r_1)^2-D\big)\big(D-(r_1-r_0)^2\big)},$$

则两圆交点可以通过标准两圆相交公式计算。你也可以使用任意等价的几何方法求解本题。

输入格式

第一行输入三个整数:

n startx starty

其中 nn 表示树的数量,startxstarty 表示狗的起始坐标。

接下来 nn 行,每行输入三个整数:

x_i y_i diameter_i

表示第 ii 棵树的圆心坐标以及直径。

输出格式

如果狗最终能够到达距离原点不超过 1010 的位置,输出它奔跑的总距离。

答案的绝对误差或相对误差不超过 10910^{-9} 即可。

如果狗会无限奔跑,输出 -1

样例 1

输入

1 -14 0
0 10 10

输出

23.64281561414452

样例 2

输入

3 0 -49
40 7 26
15 25 12
-5 11 23

输出

531.3835950099849

样例 3

输入

1 12 12
3 3 3

输出

-1.0

样例 4

输入

1 5 8
15 15 1

输出

0.0

样例解释

样例 1 中,狗先沿以原点为圆心、半径为 1414 的圆顺时针运动,跑过约 18.431923291718.4319232917 后撞到树;随后沿树的圆周逆时针运动,在又跑过约 5.21089232245.2108923224 后到达距离原点为 1010 的位置。

样例 3 中,狗始终无法撞到能够使其运动半径减小的树,因此会无限奔跑。

样例 4 中,狗的起点到原点距离已经小于 1010,所以答案为 00

数据范围和保证

  • 1n501\le n\le50
  • 1000xi,yi,startx,starty1000-1000\le x_i,y_i,startx,starty\le1000
  • 1diameteri1001\le diameter_i\le100
  • 任意两棵树的圆周之间至少相距 10610^{-6}
  • 对任意两棵树,它们相对原点的最近距离与另一棵树相对原点的最远距离不会相差不超过 10610^{-6}
  • 不会有一棵树完全覆盖以原点为圆心、半径为 1010 的圆;
  • 若一棵树与半径为 1010 的圆相交,则交叉不会处于数值上近乎相切的退化状态;
  • 狗的起点不会位于树的内部。