ZOJ 1450 Minimal Circle(HDU 3007 Buried memory)

最小圆覆盖额,上来先想到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;
}


 

你可能感兴趣的:(ZOJ 1450 Minimal Circle(HDU 3007 Buried memory))