最小圆覆盖模板

给出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

Sample Output
5.00
5.00 5.00

#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio> 
#include<algorithm>
const int maxn=1e6+6;
using namespace std;
struct Point
{
	double x,y;
	Point(double x=0,double y=0):x(x),y(y){}
	Point operator + (Point v){
		return Point(x+v.x,y+v.y);
	}
	Point operator - (Point v){
		return Point(x-v.x,y-v.y);
	}
	Point operator * (double d){
		return Point (x*d,y*d);
	}
	Point operator / (double d){
		return Point (x/d,y/d);
	}
}Dots[maxn];
typedef Point Vector;
struct Circle
{
	double r;
	Point centre;
	Circle(Point centre1=Point(0,0),double r1=0)
	{
		centre=centre1;
		r=r1;
	}
}ansC;
struct Triangle
{
	Point p[3];
};
double cross(Vector a,Vector b)
{
	return (a.x*b.y-a.y*b.x);
}
double TriangleArea(Triangle t)
{
	return fabs(cross(t.p[1]-t.p[0],t.p[2]-t.p[0]))/2.0;
}
double Distance(Point a,Point b)
{
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
Circle CircumCircleofTriangle(Triangle t)
{
	Circle tmp;
	double a,b,c,c1,c2;
	double xa,ya,xb,yb,xc,yc;
	a=Distance(t.p[0],t.p[1]);
	b=Distance(t.p[1],t.p[2]);
	c=Distance(t.p[2],t.p[0]);
	tmp.r=a*b*c/TriangleArea(t)/4.0;
	xa=t.p[0].x;
	ya=t.p[0].y;
	xb=t.p[1].x;
	yb=t.p[1].y;
	xc=t.p[2].x;
	yc=t.p[2].y;
	c1=(xa*xa+ya*ya-xb*xb-yb*yb)/2.0;
	c2=(xa*xa+ya*ya-xc*xc-yc*yc)/2.0;
	tmp.centre.x=(c1*(ya-yc)-c2*(ya-yb))/((xa-xb)*(ya-yc)-(xa-xc)*(ya-yb));
	tmp.centre.y=(c1*(xa-xc)-c2*(xa-xb))/((ya-yb)*(xa-xc)-(ya-yc)*(xa-xb));
	return tmp;
}
Circle MinCircle2(int u,Triangle t)
{
	if(u==0) return Circle(Point(0,0),-2.0);
	else if(u==1) return Circle(t.p[0],0);
	else if(u==2) return Circle(Point((t.p[0].x+t.p[1].x)/2.0,(t.p[0].y+t.p[1].y)/2.0),Distance(t.p[0],t.p[1])/2.0);
	else if(u==3) return CircumCircleofTriangle(t); 
} 
void MinCircle(int n,int u,Triangle t)
{
	ansC=MinCircle2(u,t);
	if(u==3) return;
	for(int i=1;i<=n;i++)
	{
		if(Distance(Dots[i],ansC.centre)>ansC.r){
			t.p[u]=Dots[i];
			MinCircle(i-1,u+1,t);
			Point temp=Dots[i];
			for(int j=i;j>=2;j--)
			{
				Dots[j]=Dots[j-1];
			}
			Dots[1]=temp;
		}
	}
}
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%lf%lf",&Dots[i].x,&Dots[i].y);
	}
	Triangle t;
	MinCircle(n,0,t);
	printf("%.10f\n",ansC.r);
	printf("%.10f %.10f\n",ansC.centre.x,ansC.centre.y);
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

henulmh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值