题意
平面给出一个圆
O
,同时给出另外
题解
计算几何,用了三角函数,用了余弦定理,难点在精度问题,需要处理好细节。
代码
/// by ztx
#include <cstdio>
#include <vector>
#include <cmath>
#include <algorithm>
#define sqr(x) ((x)*(x))
#define pb push_back
#define mkpr std::make_pair
typedef double lf;
typedef std::pair<lf,lf> PLF;
const lf eps = 1E-9;
const lf PI = acos(-1.0);
inline lf dist2(lf x1,lf y1,lf x2,lf y2) { return sqr(x1-x2)+sqr(y1-y2); }
std::vector<PLF> a;
std::vector<PLF>::iterator it;
int main() {
int x0, y0, v, T, n, x, y, r;
lf R, d, ang, angM, angL, angR, last, ans;
scanf("%d%d%d%d%d", &x0, &y0, &v, &T, &n);
R = (lf)v * T;
while (n --> 0) {
scanf("%d%d%d", &x, &y, &r);
d = dist2(x,y,x0,y0);
if (d < 1.0 * r * r + eps) {
printf("%.11f", 1.0);
goto END;
}
d = sqrt(d);
if (R+r < d-eps) continue;
angM = atan2(y-y0,x-x0);
if (angM < 0) angM += 2*PI;
if (sqrt(d*d-1.0*r*r) < R+eps) ang = asin(r / d);
else ang = acos((d*d+R*R-1.0*r*r) / (2*d*R));
angL = angM-ang, angR = angM+ang;
if (angL < 0) {
a.pb(mkpr(angL+2*PI,1)), a.pb(mkpr(2*PI,-1));
a.pb(mkpr(0,1)), a.pb(mkpr(angR,-1));
} else if (angR > 2*PI) {
a.pb(mkpr(angL,1)), a.pb(mkpr(2*PI,-1));
a.pb(mkpr(0,1)), a.pb(mkpr(angR-2*PI,-1));
} else {
a.pb(mkpr(angL,1)), a.pb(mkpr(angR,-1));
}
}
std::sort(a.begin(),a.end());
for (last = ans = x = 0, it = a.begin(); it != a.end(); it ++ ) {
if (x > 0) ans += it->first-last;
x += it->second;
last = it->first;
}
printf("%.11f\n", ans/(2*PI));
END:;
getchar(),getchar();
return 0;
}