最小圆覆盖额,上来先想到n^3暴力,上网搜了下算法,o(n)的神思想啊。。。
看了看众神们的代码,可不可以认为这种随机增量算法是非常非常非常高端的剪枝啊~~
话说剪枝剪到了神一样的地步也就是降围了。
求外接圆圆心用的中垂线相交的方法,毕竟中垂线不会平行的。
代码
#include<stdio.h> #include<math.h> #define X 510 struct point{ double x,y; }p[X],as; double dis(point a,point b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } point xin(point a,point b,point c){ double a1,a2,b1,b2,c1,c2,d; a1=b.x-a.x;b1=b.y-a.y;c1=(a1*a1+b1*b1)/2; a2=c.x-a.x;b2=c.y-a.y;c2=(a2*a2+b2*b2)/2; d=a1*b2-a2*b1; a.x+=(c1*b2-c2*b1)/d; a.y+=(c2*a1-c1*a2)/d; return a; } int main(){ int i,j,k,n; double r; while(scanf("%d",&n),n){ for(i=0;i<n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); as=p[0];r=0; for(i=1;i<n;i++) if(dis(as,p[i])>r){ as=p[i];r=0; for(j=0;j<i;j++) if(dis(as,p[j])>r){ as.x=(p[i].x+p[j].x)/2; as.y=(p[i].y+p[j].y)/2; r=dis(p[j],as); for(k=0;k<j;k++) if(dis(as,p[k])>r){ as=xin(p[i],p[j],p[k]); r=dis(p[i],as); } } } printf("%.2lf %.2lf %.2lf\n",as.x,as.y,r); } return 0; }