1≤N≤500000
随机增量法求最小圆覆盖裸题
#include<cmath> #include<ctime> #include<cstdio> #include<cstring> #include<cstdlib> #include<complex> #include<iostream> #include<algorithm> #include<iomanip> #include<vector> #include<string> #include<bitset> #include<queue> #include<set> #include<map> using namespace std; typedef double db; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return x*f; } void print(int x) {if(x<0)putchar('-'),x=-x;if(x>=10)print(x/10);putchar(x+'0');} const int N=501000,o=N-1; const db eps=1e-9; db x[N],y[N],r; inline db dis(int a,int b) {return sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]));} inline void geto(int a,int b,int c) { db a1,a2,b1,b2,c1,c2; a1=2*(x[b]-x[a]);b1=2*(y[b]-y[a]);c1=x[b]*x[b]-x[a]*x[a]+y[b]*y[b]-y[a]*y[a]; a2=2*(x[c]-x[a]);b2=2*(y[c]-y[a]);c2=x[c]*x[c]-x[a]*x[a]+y[c]*y[c]-y[a]*y[a]; if(abs(a1)<eps)y[o]=c1/b1,x[o]=(c2-y[o]*b2)/a2; else if(abs(b1)<eps)x[o]=c1/a1,y[o]=(c2-x[o]*a2)/b2; else x[o]=(c2*b1-c1*b2)/(a2*b1-a1*b2),y[o]=(c2*a1-c1*a2)/(b2*a1-b1*a2); } int a[N]; int main() { int n=read(); register int i,j,k; for(i=1;i<=n;++i)scanf("%lf%lf",&x[i],&y[i]),a[i]=i; random_shuffle(a+1,a+1+n); for(i=1;i<=n;++i)swap(x[a[i]],x[i]),swap(y[a[i]],y[i]); x[o]=x[1];y[o]=y[1];r=0; for(i=1;i<=n;++i) { if(dis(i,o)<r||abs(r-dis(i,o))<eps)continue; r=dis(i,1)/2;x[o]=(x[1]+x[i])/2;y[o]=(y[1]+y[i])/2; for(j=2;j<i;++j) { if(dis(j,o)<r||abs(r-dis(j,o))<eps)continue; r=dis(i,j)/2;x[o]=(x[i]+x[j])/2;y[o]=(y[i]+y[j])/2; for(k=1;k<j;++k) { if(dis(k,o)<r||abs(r-dis(k,o))<eps)continue; geto(i,j,k);r=dis(k,o); } } } printf("%.2lf %.2lf %.2lf\n",x[o],y[o],r); return 0; } /* 5 1.200 1.200 2.400 2.400 3.800 4.500 2.500 3.100 3.900 1.300 2.50 2.85 2.10 */