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 }

 

posted @ 2015-03-28 12:00  huangxf  阅读(298)  评论(0编辑  收藏  举报