凸包和最小覆盖圆问题

给出平面上的一些点,求覆盖这些点的最小圆。

具体问题可以见hdu 2215。

 

具体解法是,先求凸包,然后枚举凸包上任意3个点,若枚举的三个点构成钝角三角形,则最大半径为最长边的一半

否则,半径r=a*b*c/(4*s)其中s是面积,具体面积可以用叉乘求得,s=(向量a叉乘向量b)的绝对值的一半。

 

View Code
  1 #include<iostream>
  2 #include<string>
  3 #include<cmath>
  4 #include<algorithm>
  5 using namespace std;
  6 
  7 struct node
  8 {
  9     double x;
 10     double y;
 11 };
 12 
 13 node point[110];
 14 int n;
 15 
 16 double dist(node a,node b)
 17 {
 18     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
 19 }
 20 
 21 double mul(node p,node a,node b)
 22 {
 23     return (a.x-p.x)*(b.y-p.y)-(b.x-p.x)*(a.y-p.y);
 24 }
 25 
 26 int cmp(node a,node b)
 27 {
 28     double d=mul(point[0],a,b);
 29     if(d>0)
 30         return 1;
 31     if(d==0 && dist(point[0],a)<=dist(point[0],b))
 32         return 1;
 33     return 0;
 34 }
 35 
 36 int stack[110],top;
 37 
 38 void tubao()
 39 {
 40     stack[0]=0;
 41     stack[1]=1;
 42     top=2;
 43     for(int i=2;i<n;i++)
 44     {
 45         while(top>1 && mul(point[stack[top-2]],point[stack[top-1]],point[i])<=0)
 46             top--;
 47         stack[top++]=i;
 48     }
 49 }
 50 
 51 double max(double a,double b)
 52 {
 53     return a>b?a:b;
 54 }
 55 
 56 int main()
 57 {
 58     int i,j,k;
 59     double a,b,c,d;
 60     freopen("in.txt","r",stdin);
 61     while(scanf("%d",&n)==1 && n)
 62     {
 63         for(i=0;i<n;i++)
 64             scanf("%lf%lf",&point[i].x,&point[i].y);
 65         if(n==1)
 66         {
 67             printf("0.50\n");
 68             continue;
 69         }
 70         /**********************************///凸包
 71         k=0;
 72         for(i=1;i<n;i++)
 73         {
 74             if(point[i].x<point[k].x)
 75                 k=i;
 76             else if(point[i].x==point[k].x && point[i].y<point[k].y)
 77                 k=i;
 78         }
 79         swap(point[0],point[k]);
 80         sort(point+1,point+n,cmp);
 81         tubao();
 82         /**********************************/
 83         double ans=0,temp,ares;
 84         if(top<3)
 85         {
 86             a=dist(point[stack[0]],point[stack[1]]);
 87             printf("%0.2lf\n",a/2+0.5);
 88             continue;
 89         }
 90         for(i=0;i<top;i++)
 91         {
 92             for(j=i+1;j<top;j++)
 93             {
 94                 for(k=j+1;k<top;k++)
 95                 {
 96                     a=dist(point[stack[i]],point[stack[j]]);
 97                     b=dist(point[stack[i]],point[stack[k]]);
 98                     c=dist(point[stack[j]],point[stack[k]]);
 99                     d=max(max(a,b),c);
100                     ares=fabs(mul(point[stack[i]],point[stack[j]],point[stack[k]])); //面积的2倍
101                     if(a==d)
102                     {
103                         a=c;
104                         c=d;
105                     }
106                     else if(b==d)
107                     {
108                         b=c;
109                         c=d;
110                     }
111                     if(a*a+b*b<c*c) //钝角三角形
112                     {
113                         temp=d/2;
114                     }
115                     else
116                     {
117                         temp=a*b*c/(2*ares);
118                     }
119                     ans=max(ans,temp);
120                 }
121             }
122         }
123         printf("%.2lf\n",ans+0.5);
124     }
125     return 0;
126 }
posted @ 2012-10-09 19:30  Accept  阅读(597)  评论(0编辑  收藏  举报