HDU 3007 最小覆盖圆

题意:
一些点,求半径最小的圆能覆盖所有点。

 

题解:
我觉得随机增量特别扯。。

主要还是我弱。。

 

 

View Code
  1 #include <iostream>
  2 #include <cstdlib>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <algorithm>
  6 #include <cmath>
  7 
  8 #define N 2222
  9 #define EPS 1e-7
 10 
 11 using namespace std;
 12 
 13 struct PO
 14 {
 15     double x,y;
 16 }p[N];
 17 
 18 int n;
 19 
 20 inline void read()
 21 {
 22     for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
 23 }
 24 
 25 inline int dc(double x)
 26 {
 27     if(x>EPS) return 1;
 28     else if(x<EPS) return -1;
 29     return 0;
 30 }
 31 
 32 inline PO operator -(PO a,PO b)
 33 {
 34     PO c;
 35     c.x=a.x-b.x; c.y=a.y-b.y;
 36     return c;
 37 }
 38 
 39 inline PO operator +(PO a,PO b)
 40 {
 41     PO c;
 42     c.x=a.x+b.x; c.y=a.y+b.y;
 43     return c;
 44 }
 45 
 46 inline double getdis(PO &a,PO &b)
 47 {
 48     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
 49 }
 50 
 51 inline double cross(PO &a,PO &b,PO &c)
 52 {
 53     return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
 54 }
 55 
 56 inline PO getpoint(PO &a,PO &b,PO &c,PO &d)//直线交点 
 57 {
 58     PO ans,tp=b-a;
 59     double k1=cross(a,d,c);
 60     double k2=cross(b,c,d);
 61     ans.x=a.x+tp.x*k1/(k1+k2);
 62     ans.y=a.y+tp.y*k1/(k1+k2);
 63     return ans;
 64 }
 65 
 66 inline PO getcenter(PO a,PO b,PO c)//三角形外接圆圆心 
 67 {
 68     PO mid1,mid2,t1,t2;
 69     mid1=b-a; mid1.x*=0.5; mid1.y*=0.5; mid1=mid1+a;
 70     mid2=c-a; mid2.x*=0.5; mid2.y*=0.5; mid2=mid2+a;
 71     t1=mid1; t1.x-=b.y-a.y; t1.y+=b.x-a.x;
 72     t2=mid2; t2.x-=c.y-a.y; t2.y+=c.x-a.x;
 73     return getpoint(mid1,t1,mid2,t2);
 74 }
 75 
 76 inline void mincover(PO &c,double &r)
 77 {
 78     random_shuffle(p+1,p+1+n);
 79     c=p[1]; r=0.0;
 80     for(int i=2;i<=n;i++)
 81         if(dc(getdis(p[i],c)-r)>0)
 82         {
 83             c=p[i]; r=0.0;
 84             for(int k=1;k<i;k++)
 85                 if(dc(getdis(p[k],c)-r)>0)
 86                 {
 87                     c.x=(p[i].x+p[k].x)*0.5;
 88                     c.y=(p[i].y+p[k].y)*0.5;
 89                     r=getdis(p[k],c);
 90                     for(int j=1;j<k;j++)
 91                         if(dc(getdis(p[j],c)-r)>0)
 92                         {
 93                             c=getcenter(p[i],p[k],p[j]);
 94                             r=getdis(p[i],c);
 95                         }
 96                 }
 97         }
 98 }
 99 
100 inline void go()
101 {
102     PO c; double r;
103     mincover(c,r);
104     printf("%.2lf %.2lf %.2lf\n",c.x,c.y,r);
105 }
106 
107 int main()
108 {
109     while(scanf("%d",&n),n) read(),go();
110     return 0;
111 }

 

 

posted @ 2013-02-26 23:31  proverbs  阅读(244)  评论(0编辑  收藏  举报