1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
| #include <cmath>
#include <cstdio>
#include <vector>
#include <algorithm>
using std::pair;
using std::vector;
inline long double sqr(const long double x) { return x*x; }
inline long double dist(const long double x1, const long double y1, const long double x2, const long double y2)
{ return std::sqrt(sqr(x1-x2) + sqr(y1-y2)); }
inline long double angle(const long double A, const long double B, const long double C)
{ return std::acos((sqr(A)+sqr(B)-sqr(C))/(2*A*B)); }
inline int sign(const long double x)
{
static const long double EPS = 1e-8;
if (x > EPS) return 1;
return x < -EPS ? -1 : 0;
}
const int MAXN = 1000;
const long double PI = std::acos(-1.0);
int n;
double R[MAXN], A[MAXN], B[MAXN];
vector< pair<long double, long double> > seg, cover;
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; ++i)
scanf("%lf%lf%lf", R+i, A+i, B+i);
long double ans = .0;
for (int i = 0; i < n; ++i)
{
seg.clear();
bool covered = false;
for (int j = i+1; j < n; ++j)
{
const long double d = dist(A[i], B[i], A[j], B[j]);
if (sign(R[j]-R[i]) >= 0 && sign(d-(R[j]-R[i])) <= 0)
{
covered = true;
break;
}
if (sign(d-(R[j]+R[i])) >= 0 || sign(d-std::abs(R[j]-R[i])) <= 0)
continue;
const long double alpha = std::atan2(B[j]-B[i], A[j]-A[i]);
const long double beta = angle(R[i], d, R[j]);
const pair<long double, long double> tmp(alpha-beta, alpha+beta);
if (sign(tmp.first) <= 0 && sign(tmp.second) <= 0)
seg.push_back(pair<long double, long double>(2*PI+tmp.first, 2*PI+tmp.second));
else if (sign(tmp.first) < 0)
{
seg.push_back(pair<long double, long double>(2*PI+tmp.first, 2*PI));
seg.push_back(pair<long double, long double>(0, tmp.second));
}
else
seg.push_back(tmp);
}
if (covered)
continue;
seg.push_back(pair<long double, long double>(10, 10));
std::sort(seg.begin(), seg.end());
long double ang = 0, lef = 0, rig = 0;
for (vector< pair<long double, long double> >::iterator iter = seg.begin(); iter != seg.end(); ++iter)
{
if (sign(rig - iter->first) >= 0)
rig = std::max(rig, iter->second);
else
{
ang += rig-lef;
lef = iter->first, rig = iter->second;
}
}
ans += R[i]*(2*PI-ang);
}
printf("%.3f", static_cast<double>(ans));
}
|