题意 : 不说了自己看
题解 : 做这个题就像发现了新大陆,因为发现了一个计算几何的乱搞的方法,就是如果让你找一个点的话我们就可以把一个圆或者一个线段等分成若干份就好了,等分成若干份然后暴力 或者加点什么优化这类的东西,这个题就是这样啊.
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;
const int maxn = 55;
const double eps = 1e-8;
const double INF = 1e30;
const int di = 2505;
const double PI = 3.141592653589793;
const int N = 3e5 + 5;
struct point {
double x,y;
}p[N];
int n,m;
int cnt = 0;
int tot ;
struct circle {
point o;
double r;
}c[maxn];
point poly[N];
point init;
struct res {
point a,b,c;
}r[maxn];
int sgn (double x) {
if (fabs (x) <= eps) return 0;
return x > 0 ? 1 : -1;
}
double cross (point a,point b,point c) {
return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);
}
double dist (point a,point b) {
return sqrt ((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
bool cmp (const point a,const point b) {
if (sgn (cross (init,a,b)) == 0) return dist (init,a) < dist (init,b);
return sgn (cross (init,a,b)) > 0;
}
void tubao () {
tot = 0;
poly[++ tot] = p[1],poly[++ tot] = p[2];
for (int i = 3;i <= cnt; ++ i) {
while (tot >= 2) {
point p1 = poly[tot];
point p2 = poly[tot - 1];
point p3 = p[i];
if (sgn (cross (p2,p1,p3)) <= 0) tot --;
else break;
}
poly[++ tot] = p[i];
}
}
int main () {
while (~scanf ("%d%d",&n,&m)) {
cnt = tot = 0;
for (int i = 1;i <= n; ++ i) {
scanf ("%lf%lf%lf",&c[i].o.x,&c[i].o.y,&c[i].r);
point temp = c[i].o;
double R = c[i].r;
for (int j = 0;j <= di; ++ j) {
p[++ cnt] = {temp.x + R * cos (2 * PI * double (j) / di),temp.y + R * sin (2 * PI * double (j) / di)};
}
}
for (int i = 1;i <= m; ++ i) {scanf ("%lf%lf%lf%lf%lf%lf",&r[i].a.x,&r[i].a.y,&r[i].b.x,&r[i].b.y,&r[i].c.x,&r[i].c.y);
p[++ cnt] = r[i].a,p[++ cnt] = r[i].b,p[++ cnt] = r[i].c;
}
double ans = 0;
for (int i = 1;i <= cnt; ++ i) {
if (p[i].y < p[1].y || (sgn (p[i].y - p[1].y) == 0 && p[i].x < p[1].x)) swap (p[i],p[1]);
}
init = p[1];
sort (p + 1,p + cnt + 1,cmp);
tubao ();
poly[tot + 1] = poly[1];
for (int i = 1;i <= tot; ++ i) {
ans += dist (poly[i],poly[i + 1]);
}
printf("%.10f\n",ans);
}
return 0;
}