bzoj1336: [Balkan2002]Alien最小圆覆盖
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1336
1336: [Balkan2002]Alien最小圆覆盖
Time Limit: 1 Sec Memory Limit: 162 MBSec Special JudgeSubmit: 1608 Solved: 713
[Submit][Status][Discuss]
Description
给出N个点,让你画一个最小的包含所有点的圆。
Input
先给出点的个数N,2<=N<=100000,再给出坐标Xi,Yi.(-10000.0<=xi,yi<=10000.0)
Output
输出圆的半径,及圆心的坐标
Sample Input
6
8.0 9.0
4.0 7.5
1.0 2.0
5.1 8.7
9.0 2.0
4.5 1.0
8.0 9.0
4.0 7.5
1.0 2.0
5.1 8.7
9.0 2.0
4.5 1.0
Sample Output
5.00
5.00 5.00
5.00 5.00
HINT
Source
最小圆覆盖裸题。
至于最小圆覆盖怎么写,看这篇博客吧,挺详细的http://blog.sina.com.cn/s/blog_6e63f59e010120dl.html
好久没写博客了……
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 #define maxn 100005 7 using namespace std; 8 int n; 9 double r; 10 const double eps=1e-9; 11 struct fuck{double x,y;}p[maxn],o; 12 fuck operator +(fuck x,fuck y){return (fuck){x.x+y.x,x.y+y.y};} 13 fuck operator -(fuck x,fuck y){return (fuck){x.x-y.x,x.y-y.y};} 14 fuck operator *(fuck x,double y){return (fuck){x.x*y,x.y*y};} 15 fuck operator /(fuck x,double y){return (fuck){x.x/y,x.y/y};} 16 double sqr(double x){return x*x;} 17 double dis(fuck x,fuck y){return sqr(x.x-y.x)+sqr(x.y-y.y);} 18 void get(fuck x,fuck y,double &a,double &b,double &c){ 19 a=2*(y.x-x.x);b=2*(y.y-x.y);c=(sqr(x.x)+sqr(x.y)-sqr(y.x)-sqr(y.y)); 20 } 21 void calc(double a,double b,double c,double d,double e,double f){ 22 o.y=(a*f-c*d)/(b*d-e*a); 23 o.x=(b*f-c*e)/(a*e-b*d); 24 } 25 int main(){ 26 srand(1315313); 27 scanf("%d",&n); 28 for(int i=1;i<=n;i++)scanf("%lf%lf",&p[i].x,&p[i].y); 29 random_shuffle(p+1,p+n+1); 30 o=p[1];r=0; 31 for(int i=2;i<=n;i++)if(dis(o,p[i])>r){ 32 o=p[i];r=0; 33 for(int j=1;j<i;j++)if(dis(p[j],o)>r){ 34 o=(p[j]+p[i])/2;r=dis(p[j],o); 35 for(int k=1;k<j;k++)if(dis(p[k],o)>r){ 36 double a,b,c,d,e,f; 37 get(p[i],p[j],a,b,c);get(p[j],p[k],d,e,f); 38 calc(a,b,c,d,e,f);r=dis(o,p[k]); 39 } 40 } 41 } 42 printf("%f\n",sqrt(r)); 43 printf("%f %f\n",o.x,o.y); 44 }