zoj 1450 Minimal Circle 最小覆盖圆

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=450

You are to write a program to find a circle which covers a set of points and has the minimal area. There will be no more than 100 points in one problem.

题意描述:找到一个最小圆能够包含到所有的二维坐标点。

算法分析:最小覆盖圆的做法。

  1 //最小覆盖圆

  2 #include<iostream>

  3 #include<cstdio>

  4 #include<cstring>

  5 #include<cstdlib>

  6 #include<cmath>

  7 #include<algorithm>

  8 #define inf 0x7fffffff

  9 #define exp 1e-10

 10 #define PI 3.141592654

 11 using namespace std;

 12 const int maxn=1000+10;

 13 struct Point

 14 {

 15     double x,y;

 16     Point(double x=0,double y=0):x(x),y(y){}

 17 }an[maxn],d;//d:最小覆盖圆的圆心坐标

 18 double r;//最小覆盖圆的半径

 19 typedef Point Vector;

 20 Vector operator + (Vector A,Vector B) {return Vector(A.x+B.x , A.y+B.y); }

 21 Vector operator - (Vector A,Vector B) {return Vector(A.x-B.x , A.y-B.y); }

 22 Vector operator * (Vector A,double p) {return Vector(A.x*p , A.y*p); }

 23 Vector operator / (Vector A,double p) {return Vector(A.x/p , A.y/p); }

 24 int dcmp(double x)

 25 {

 26     if (fabs(x)<exp) return 0;

 27     return x<0 ? -1 : 1;

 28 }

 29 double cross(Vector A,Vector B)

 30 {

 31     return A.x*B.y-B.x*A.y;

 32 }

 33 double dist(Vector A,Vector B)

 34 {

 35     double x=(A.x-B.x)*(A.x-B.x);

 36     double y=(A.y-B.y)*(A.y-B.y);

 37     return sqrt(x+y);

 38 }

 39 

 40 void MiniDiscWith2Point(Point p,Point q,int n)

 41 {

 42     d=(p+q)/2.0;

 43     r=dist(p,q)/2;

 44     int k;

 45     double c1,c2,t1,t2,t3;

 46     for (k=1 ;k<=n ;k++)

 47     {

 48         if (dist(d,an[k])<=r) continue;

 49         if (dcmp(cross(p-an[k],q-an[k]))!=0)

 50         {

 51             c1=(p.x*p.x+p.y*p.y-q.x*q.x-q.y*q.y)/2.0;

 52             c2=(p.x*p.x+p.y*p.y-an[k].x*an[k].x-an[k].y*an[k].y)/2.0;

 53             d.x=(c1*(p.y-an[k].y)-c2*(p.y-q.y))/((p.x-q.x)*(p.y-an[k].y)-(p.x-an[k].x)*(p.y-q.y));

 54             d.y=(c1*(p.x-an[k].x)-c2*(p.x-q.x))/((p.y-q.y)*(p.x-an[k].x)-(p.y-an[k].y)*(p.x-q.x));

 55             r=dist(d,an[k]);

 56         }

 57         else

 58         {

 59             t1=dist(p,q);

 60             t2=dist(q,an[k]);

 61             t3=dist(p,an[k]);

 62             if (t1>=t2 && t1>=t3)

 63             {

 64                 d=(p+q)/2.0;

 65                 r=dist(p,q)/2.0;

 66             }

 67             else if (t2>=t1 && t2>=t3)

 68             {

 69                 d=(an[k]+q)/2.0;

 70                 r=dist(an[k],q)/2.0;

 71             }

 72             else

 73             {

 74                 d=(an[k]+p)/2.0;

 75                 r=dist(an[k],p)/2.0;

 76             }

 77         }

 78     }

 79 }

 80 void MiniDiscWithPoint(Point p,int n)

 81 {

 82     d=(p+an[1])/2.0;

 83     r=dist(p,an[1])/2.0;

 84     int j;

 85     for (j=2 ;j<=n ;j++)

 86     {

 87         if (dist(d,an[j])<=r) continue;

 88         else

 89         {

 90             MiniDiscWith2Point(p,an[j],j-1);

 91         }

 92     }

 93 }

 94 

 95 int main()

 96 {

 97     int n;

 98     while (scanf("%d",&n)!=EOF && n)

 99     {

100         for (int i=1 ;i<=n ;i++)

101         {

102             scanf("%lf%lf",&an[i].x,&an[i].y);

103         }

104         if (n==1)

105         {

106             printf("%lf %lf\n",an[1].x,an[1].y);

107             continue;

108         }

109         r=dist(an[1],an[2])/2.0;

110         d=(an[1]+an[2])/2.0;

111         for (int i=3 ;i<=n ;i++)

112         {

113             if (dist(d,an[i])<=r) continue;

114             else

115             MiniDiscWithPoint(an[i],i-1);

116         }

117         printf("%.2lf %.2lf %.2lf\n",d.x,d.y,r);

118     }

119     return 0;

120 }

 

你可能感兴趣的:(ini)