链接 : https://codeforces.com/gym/101955/problem/L
本来是过了的…但看了大佬的代码之后开始怀疑自己是怎么卡过去的
大佬的代码:
#include <bits/stdc++.h> using namespace std; const double Pi=acos(-1); const double eps=1e-12; const int N=1e5+5; struct Point { double x,y; Point(double x=0,double y=0):x(x),y(y) {}; }; Point operator +(Point A,Point B) { return Point(A.x+B.x,A.y+B.y); } Point operator -(Point A,Point B) { return Point(A.x-B.x,A.y-B.y); } Point operator *(Point A,double B) { return Point(A.x*B,A.y*B); } Point operator /(Point A,double B) { return Point(A.x/B,A.y/B); } int dcmp(double x) { if(fabs(x)<eps)return 0; return x<0?-1:1; } bool operator<(const Point&a,const Point&b) { return a.x<b.x||(a.x==b.x&&a.y<b.y); } bool operator == (const Point &a,const Point &b) { return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0; } double Dot(Point A,Point B) { return A.x*B.x+A.y*B.y; } double Length(Point A) { return sqrt(Dot(A,A)); } double Cross(Point A,Point B) { return A.x*B.y-A.y*B.x; } double Angle(Point A,Point B) {//利用点积 求出向量 A B 的夹角 cos值 return acos(Dot(A,B)/Length(A)/Length(B)); } double Angle(Point A) { return atan2(A.y, A.x); } struct Circle { //圆 Point c; double r; Circle(Point c = Point(0, 0), double r = 0):c(c),r(r) {} Point point(double a) { return Point(c.x+cos(a)*r,c.y+sin(a)*r); } }; double dis(Point A,Point B) { return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y)); } int circle_circle(Circle C1,Circle C2,vector<Point>&sol) { //圆与圆的交点,核心思想就是利用余弦定理求出两交点与圆心连线的夹角,显然可以根据已知距离,和圆心坐标,求出交点坐标,不同去画图,高中几何知识 double d=Length(C1.c-C2.c); if(dcmp(d)==0) { if(dcmp(C1.r-C2.r)==0)return -1; return 0; } if(dcmp(C1.r+C2.r-d)<0)return 0; if(dcmp(fabs(C1.r-C2.r)-d)>0)return 0; double a=Angle(C2.c-C1.c); double da=acos((C1.r*C1.r+d*d-C2.r*C2.r)/(2*d*C1.r)); Point p1=C1.point(a-da),p2=C1.point(a+da); sol.push_back(p1); if(p1==p2)return 1; sol.push_back(p2); return 2; } //由此往上的全部,即为两圆交点模板 //解方程无法换算不同的精度,而该方法可以有不同的eps,且精度和速度都比解方程更优秀 int T,n; double R; Point p[N]; double r[N]; int check(Point A) { for(int i=1; i<=n; i++) { double h=dis(A,p[i]); if(h<r[i]+eps)return 0; } return 1; } int main() { cin>>T; int kase=0; while(T--) { cin>>n>>R; Circle C0; C0.c=Point(0,0); C0.r=R; vector<Point>v; for(int i=1; i<=n; i++) { double x,y,z; scanf("%lf%lf%lf",&x,&y,&z); p[i]=Point(x,y); r[i]=z; Circle C1; C1.c=Point(x,y); C1.r=z; circle_circle(C0,C1,v); } double ans=0; int f=0; for(int i=0; i<v.size(); i++) { double x=-v[i].x; double y=-v[i].y; if(check(Point(x,y))) { f=1; break; } } if(f or v.size()==0) { printf("Case #%d: %.10lf\n",++kase,R*2); continue; } int h=v.size(); for(int i=0; i<h; i++) { for(int j=0; j<h; j++) { if(i==j)continue; double res=dis(v[i],v[j]); ans=max(ans,res); } } printf("Case #%d: %.15lf\n",++kase,ans); } return 0; }