【题目大意】:给出你T个case。每个case有n个点,叫你求这个点的半径和圆心坐标,使得这个圆覆盖所有的点(n<=100000)
【解题思路】:曾经在zoj上做过一道最小圆的覆盖,但是那道题的点只有100,当初是暴力做的。显然碰到这个数据量是行不通的,我们可以采取dfs进行增量,或者利用随机重排进行增量,二者在spoj上测试的时间差距不大,网络模版testing。
【代码】:
dfs实现增量
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <queue> #include <cmath> #include <string> #include <cctype> #include <map> #include <iomanip> using namespace std; #define eps 1e-8 #define pi acos(-1.0) #define inf 1<<30 #define linf 1LL<<60 #define pb push_back #define lc(x) (x << 1) #define rc(x) (x << 1 | 1) #define lowbit(x) (x & (-x)) #define ll long long int n; struct Point{ double x; double y; }pt[1005]; struct Traingle{ struct Point p[3]; }; struct Circle{ struct Point center; double r; }ans; //计算两点距离 double Dis(struct Point p, struct Point q){ double dx=p.x-q.x; double dy=p.y-q.y; return sqrt(dx*dx+dy*dy); } //计算三角形面积 double Area(struct Traingle ct){ return fabs((ct.p[1].x-ct.p[0].x)*(ct.p[2].y-ct.p[0].y)-(ct.p[2].x-ct.p[0].x)*(ct.p[1].y-ct.p[0].y))/2.0; } //求三角形的外接圆,返回圆心和半径(存在结构体"圆"中) struct Circle CircumCircle(struct Traingle t){ struct Circle tmp; double a,b,c,c1,c2; double xA,yA,xB,yB,xC,yC; a=Dis(t.p[0],t.p[1]); b=Dis(t.p[1],t.p[2]); c=Dis(t.p[2],t.p[0]); //根据S = a * b * c / R / 4;求半径R tmp.r=(a*b*c)/(Area(t)*4.0); xA=t.p[0].x; yA=t.p[0].y; xB=t.p[1].x; yB=t.p[1].y; xC=t.p[2].x; yC=t.p[2].y; c1=(xA*xA+yA*yA-xB*xB-yB*yB)/2; c2=(xA*xA+yA*yA-xC*xC-yC*yC)/2; tmp.center.x=(c1*(yA-yC)-c2*(yA-yB))/((xA-xB)*(yA-yC)-(xA-xC)*(yA-yB)); tmp.center.y=(c1*(xA-xC)-c2*(xA-xB))/((yA-yB)*(xA-xC)-(yA-yC)*(xA-xB)); return tmp; } //确定最小包围圆 struct Circle MinCircle(int num, struct Traingle ct){ struct Circle ret; if (num==0) ret.r=0.0; else if (num==1){ ret.center=ct.p[0]; ret.r = 0.0; } else if (num==2){ ret.center.x=(ct.p[0].x+ct.p[1].x)/2.0; ret.center.y=(ct.p[0].y+ct.p[1].y)/2.0; ret.r=Dis(ct.p[0], ct.p[1])/2.0; } else if(num==3) ret=CircumCircle(ct); return ret; } //递归实现增量算法 void Dfs(int x, int num, struct Traingle ct){ int i, j; struct Point tmp; ans = MinCircle(num, ct); if (num==3) return; for (i=1; i<=x; i++) if (Dis(pt[i],ans.center)>ans.r){ ct.p[num]=pt[i]; Dfs(i-1,num+1,ct); tmp=pt[i]; for (j=i; j>=2; j--) pt[j]=pt[j-1]; pt[1]=tmp; } } void Solve(int n){ struct Traingle ct; Dfs(n,0,ct); } int main(){ int T; cin >> T; while (T--){ scanf("%d",&n); if (n==0) break; for (int i=1; i<=n; i++) scanf("%lf %lf",&pt[i].x,&pt[i].y); Solve(n); printf("%.2f\n",ans.r); printf("%.2f %.2f\n",ans.center.x,ans.center.y); } return 0; }
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <queue> #include <cmath> #include <string> #include <cctype> #include <map> #include <iomanip> using namespace std; #define eps 1e-10 #define pi acos(-1.0) #define inf 1<<30 #define linf 1LL<<60 #define pb push_back #define lc(x) (x << 1) #define rc(x) (x << 1 | 1) #define lowbit(x) (x & (-x)) #define ll long long const int N=100010; int n; struct cpoint { double x, y; }cp[N]; int dcmp(double x) { if (x < -eps) return -1; else return x > eps; } double sqr(double x) { return x * x; } double dis(cpoint p1,cpoint p2) { return sqrt(sqr(p1.x-p2.x)+sqr(p1.y-p2.y)); } void center(cpoint p0, cpoint p1, cpoint p2, cpoint &cp) { //三角形外心 double a1=p1.x-p0.x,b1=p1.y-p0.y,c1=(sqr(a1)+sqr(b1))/2; double a2=p2.x-p0.x,b2=p2.y-p0.y,c2=(sqr(a2)+sqr(b2))/2; double d=a1*b2-a2*b1; cp.x=p0.x+(c1*b2-c2*b1)/d; cp.y=p0.y+(a1*c2-a2*c1)/d; } void MinCir(cpoint cp[], int n, cpoint &c, double &r) { random_shuffle(cp, cp + n); c = cp[0]; r = 0; for (int i = 1; i < n; ++i) { if (dcmp(dis(cp[i], c) - r) <= 0) continue; c = cp[i]; r = 0; for (int j = 0; j < i; ++j) { if (dcmp(dis(cp[j], c) - r) <= 0) continue; c.x = (cp[i].x + cp[j].x) / 2; c.y = (cp[i].y + cp[j].y) / 2; r = dis(c, cp[j]); for (int k = 0; k < j; ++k) { if (dcmp(dis(cp[k], c) - r) <= 0) continue; center(cp[i], cp[j], cp[k], c); r = dis(c, cp[k]); } } } } void solve() { scanf("%d",&n); for (int i=0; i<n; ++i) { scanf("%lf%lf",&cp[i].x,&cp[i].y); } cpoint c; double r; MinCir(cp,n,c,r); printf("%.2f\n%.2f %.2f\n",r,c.x,c.y); } int main() { int T; cin >> T; while (T--) { solve(); } return 0; }