据说可以将圆划分成连续的小线段,大概250个差不多了
关键是二维凸包的Graham算法
#include <cstdio> #include <cmath> #include <algorithm> using namespace std; const int MAXN = 50100; const int cut = 250; const double eps = 1e-8; double pi,pc; inline int zero(double a) { if (a > eps) return 1; if (a < -eps) return -1; return 0; } struct _POINT { double x, y; int cent; _POINT (){}; _POINT (double a, double b, int c = -1) {x = a; y = b; cent=c;} double operator ^ (const _POINT & exa) { return x*exa.y - y*exa.x; } _POINT operator - (const _POINT & a) { return _POINT(x - a.x, y - a.y); } }pt[MAXN]; inline double dis(const _POINT & a, const _POINT & b) { return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)); } int npt, n, m, top, stk[MAXN]; double rr[3][MAXN]; bool cmp(_POINT a, _POINT b) { double cax = (a - pt[0]) ^ (b - pt[0]); if (zero(cax) > 0) return true; if (zero(cax) < 0) return false; if (zero(dis(pt[0], a) - dis(pt[0], b)) < 0) return true; return false; } void Graham() { _POINT p0 = pt[0]; int k = 0; for (int i = 1; i< npt; ++i) { if (pt[i].y == p0.y) { if (pt[i].x < p0.x) k = i, p0 = pt[i]; } else if (pt[i].y < p0.y) k = i, p0 = pt[i]; } swap(pt[0], pt[k]); sort(pt+1, pt+npt, cmp); stk[0] = 0; stk[1] = 1; top = 2; for (int i = 2; i< npt; ++i) { while (top > 1 && zero((pt[stk[top-1]]-pt[stk[top-2]]) ^ (pt[i]-pt[stk[top-1]])) <= 0) top--; stk[top++] = i; } } double solve() { double res = 0.0; stk[top++] = 0; for (int i = 1; i< top; ++i) { int u = stk[i-1], v = stk[i]; if (pt[u].cent == pt[v].cent) { res += rr[2][pt[v].cent]*pi/cut; } else { res += dis(pt[u], pt[v]); } } return res; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); #endif pi = acos(-1.0)*2.0; pc = pi/cut; while (scanf("%d%d", &n, &m) != EOF) { npt = 0; for (int i = 0; i< n; ++i) { double x, y, r, t = 0.0, xx, yy; scanf("%lf%lf%lf", &x, &y, &r); rr[0][i] = x;rr[1][i] = y;rr[2][i] = r; for (int j = 0; j< cut; ++j, t+=pc) { xx = x + r*cos(t); yy = y + r*sin(t); _POINT pp(xx, yy, i); pt[npt] = pp; npt++; } } for (int i = 0; i< m; ++i) { for (int j = 0; j< 3; ++j) { double x, y; scanf("%lf%lf", &x, &y); _POINT pp (x, y, npt); pt[npt] = pp; npt++; } } Graham(); printf("%.5lf\n", solve()); } return 0; }