Geometry problem ...
Save all the circles first, and then for each circle we have to get down after the circle block the part, ask for a set, and the perimeter is not blocked into the answer.
#include <cstdlib> #include <cstdio> #include <iostream> #include <cstring> #include <cmath > #include <cctype> #include <algorithm> #define REP (i, L, R) for (int i=l; i<=r; i++) #define PI ACOs ( -1) #d Efine maxn 1234typedef Long ll;using namespace Std;inline int read () {int x=0, f=1; char Ch=getchar (); while (!isdigit ( CH)) {if (ch== '-') f=-1; Ch=getchar ();} while (IsDigit (CH)) x=x*10+ch-' 0 ', Ch=getchar (); return x*f;} struct line{double L, R;} Q[maxn*2];bool CMP (line A, line B) {return A.L<B.L | | (A.L==B.L && A.R<B.R);} Double R[MAXN], X[MAXN], Y[MAXN];d ouble dis (int a, int b) {return sqrt ((X[a]-x[b]) * (X[a]-x[b]) + (Y[a]-y[b]) * (Y[a]-y[b])) ;} int main () {int n=read (), double Ans=0;rep (i, 1, N) scanf ("%lf%lf%lf", &r[i], &x[i], &y[i]); Rep (A, 1, n) {int to P=0; BOOL End=0; Rep (b, a+1, N) if (R[a]+dis (A, b) <=r[b]) end=1; if (end) Continue;rep (b, a+1, N) if (R[b]+dis (A, b) >r[a] && R[a]+r[b]>dis (A, B)) {double r1=r[a], r2=r[b], D=dis (A, b), T, V;t=acos ((r1*r1-r2*r2+d*d)/(2*D)/r1), V=atan2 ((X[a]-x[b)), (Y[a]-y[b])); q[++top]= (line) {v-t, v+t};} Rep (i, 1, top) {if (q[i].l<0) q[i].l+=2*pi;if (Q[I].L>2*PI) q[i].l-=2*pi;if (q[i].r<0) q[i].r+=2*pi;if (q[i].r& GT;2*PI) q[i].r-=2*pi;if (Q[I].L>Q[I].R) q[++top]= (line) {0,Q[I].R}, Q[i].r=2*pi;} Sort (q+1, q+top+1, CMP);d ouble now=0, Tmp=0;rep (i, 1, top) {if (Q[i].l>now) Tmp+=q[i].l-now;now=max (now, Q[I].R);} Tmp+=2*pi-now;ans+=tmp*r[a];} printf ("%.3lf\n", ans); return 0;}
BZOJ-1043 [HAOI2008] Falling disk