题意:$n$个点,求最小圆覆盖,$n \leq 5e5$
这题数据是随机的hhh
我们可以先求出凸包然后对凸包上的点求最小圆覆盖…(不过直接求应该也行?)
反正随便写好像都能过…
#include<cstdio> #include<algorithm> #include<cstdlib> #include<cmath> using namespace std; const int N=500005; struct Point { double x,y; int rnd; Point(double x=0,double y=0):x(x),y(y){} }p[N],s[N]; struct Line { double k,b; }; inline bool cmp1(Point a,Point b) { if(a.x==b.x)return a.y<b.y; return a.x<b.x; } inline bool cmp2(Point a,Point b) { return a.rnd<b.rnd; } inline Point operator +(Point a,Point b) { return Point(a.x+b.x,a.y+b.y); } inline Point operator -(Point a,Point b) { return Point(a.x-b.x,a.y-b.y); } inline Point operator /(Point a,double d) { return Point(a.x/d,a.y/d); } inline double cross(Point a,Point b) { return a.x*b.y-a.y*b.x; } inline double sqr2(double x) { return x*x; } inline double dist(Point a,Point b) { return sqrt(sqr2(a.x-b.x)+sqr2(a.y-b.y)); } inline Line getLine(double k,Point a) { Line res;res.k=k; res.b=a.y-a.x*k; return res; } inline Point getLineIntersection(Line l1,Line l2) { Point res; res.x=(l2.b-l1.b)/(l1.k-l2.k); res.y=res.x*l1.k+l1.b; return res; } inline Point getCircle(Point a,Point b,Point c) { Point p1=(a+b)/2,p2=(a+c)/2; double k1=-(b.x-a.x)/(b.y-a.y); double k2=-(c.x-a.x)/(c.y-a.y); Line l1=getLine(k1,p1),l2=getLine(k2,p2); return getLineIntersection(l1,l2); } inline Point minCircle(double &r,int n) { for(register int i=1;i<=n;i++)s[i].rnd=rand(); sort(s+1,s+n+1,cmp2); Point o=s[1];r=0; for(register int i=2;i<=n;i++)if(r<dist(o,s[i])) { o=s[i];r=0; for(register int j=1;j<i;j++)if(r<dist(o,s[j])) { o=(s[i]+s[j])/2; r=dist(o,s[i]); for(register int k=1;k<j;k++)if(r<dist(o,s[k])) { o=getCircle(s[i],s[j],s[k]); r=dist(o,s[i]); } } } return o; } inline int convexHull(int n) { sort(p+1,p+n+1,cmp1); int t=0,k; for(register int i=1;i<=n;i++) { while(t>1&&cross(s[t]-s[t-1],p[i]-s[t-1])<0)t--; s[++t]=p[i]; } k=t; for(register int i=n-1;i>=1;i--) { while(t>k&&cross(s[t]-s[t-1],p[i]-s[t-1])<0)t--; s[++t]=p[i]; } if(n>1)t--; return t; } int main() { int n;scanf("%d",&n); for(register int i=1;i<=n;i++)scanf("%lf%lf",&p[i].x,&p[i].y); int t=convexHull(n);double r; Point res=minCircle(r,t); printf("%.2lf %.2lf %.2lf",res.x,res.y,r); return 0; }