题目链接:https://ac.nowcoder.com/acm/problem/19959
题目大意:

思路:我们考虑有一条直线把这些点,分割成两个部分。分别做一个最小圆覆盖。半径取max(R1, R2)。

我们可以考虑旋转坐标系来枚举直线的斜率。那么对一条特定的坐标系。按坐标轴就可以二分一下。得到最优的半径。


只要旋转180度就够了。

#include<bits/stdc++.h>
#define db double
#define eps 1e-9
const db ki=1.0/180*acos(-1);
const db co=cos(ki),si=sin(ki);
using namespace std;

const int N=1e3+5;
db r=0.0;
struct point{db x,y;}o,a[N],p[N];

inline point rotate(const point &b){
	point t;
	t.x=b.x*co+b.y*si;
	t.y=b.y*co-b.x*si;
	return t;
}
struct line{db a,b,c;};
inline db pow2(db x){return x*x;}
inline db dis(point a,point b){return sqrt(pow2(a.x-b.x)+pow2(a.y-b.y));}
inline bool check(point x){return dis(o,x)<=r+eps;}
inline point con(line a,line b){return point{(b.c*a.b-a.c*b.b)/(a.a*b.b-a.b*b.a),(b.c*a.a-a.c*b.a)/(a.b*b.a-b.b*a.a)};}
inline db check(int ll,int rr){
	if(ll>rr) return 0;
	for(int i=ll;i<=rr;i++) p[i]=a[i];
	for(int i=ll; i<=rr; i++){
		//cout<<p[i].x<<" "<<p[i].y<<endl;
	}

	random_shuffle(p+ll,p+rr+1);
	o=p[ll];r=0.0;
	for(int i=ll;i<=rr;i++)
		if(!check(p[i])){
			o.x=p[i].x,o.y=p[i].y;r=0;
			for(int j=ll;j<i;j++)
				if(!check(p[j])){
					o.x=(p[i].x+p[j].x)/2,o.y=(p[i].y+p[j].y)/2;
					r=dis(o,p[j]);
					for(int k=ll;k<j;k++)
						if(!check(p[k])){
							o=con(line{2*(p[i].x-p[k].x),2*(p[i].y-p[k].y),pow2(p[k].x)+pow2(p[k].y)-pow2(p[i].x)-pow2(p[i].y)},line{2*(p[i].x-p[j].x),2*(p[i].y-p[j].y),pow2(p[j].x)+pow2(p[j].y)-pow2(p[i].x)-pow2(p[i].y)});
                			r=dis(p[k],o);
						}
				}
		}
	return r;
}

int main()
{
    int n;
    while(scanf("%d", &n), n){

        double R=1e9;
        for(int i=1; i<=n; i++) scanf("%lf%lf", &a[i].x, &a[i].y);
        for(int i=1; i<=180; i++){//坐标系旋转
            for(int i=1; i<=n; i++) a[i]=rotate(a[i]);
            sort(a+1, a+n+1, [](point &a, point &b){return a.x<b.x;});
            int l=1, r=n;
            while(l<=r){
                int mid=(l+r)/2;
                double R1=check(1, mid);
                double R2=check(mid+1, n);
                if(min(R1, R2)>R){//剪枝
                    break;
                }
                if(R1<R2){
                    l=mid+1;
                }
                else{
                    r=mid-1;
                }
                R=min(R, max(R1, R2));
            }
        }

        printf("%.2f\n", R);
    }

    return 0;
}