最小圆覆盖——模板题

#include <bits/stdc++.h>
const int maxn = 1005;
struct TPoint
{
	double x, y;
	TPoint operator - (const TPoint &a) const
	{
		TPoint p1;
		p1.x = x - a.x;
		p1.y = y - a.y;
		return p1;
	}
};
struct TCircle
{
	double r;
	TPoint centre;
};
struct TTriangle
{
	TPoint t[3];
};
TCircle c;
TPoint a[maxn];
double distance(TPoint p1, TPoint p2)
{
	TPoint p3;
	p3.x = p2.x - p1.x;
	p3.y = p2.y - p1.y;
	return sqrt(p3.x * p3.x + p3.y * p3.y);
}
double triangleArea(TTriangle t)
{
	TPoint p1, p2;
	p1 = t.t[1] - t.t[0];
	p2 = t.t[2] - t.t[0];
	return fabs(p1.x * p2.y - p1.y * p2.x) / 2;
}
TCircle circumcirleOfTriangle(const TTriangle t)
{
	TCircle tmp;
	double a, b, c, c1, c2;
	double xa, ya, xb, yb, xc, yc;
	a = distance(t.t[0], t.t[1]);
	b = distance(t.t[1], t.t[2]);
	c = distance(t.t[2], t.t[0]);
	printf("a = %lf b = %lf c = %lf\n", a, b, c);
	tmp.r = a * b * c / triangleArea(t) / 4;
	xa = t.t[0].x; ya = t.t[0].y;
	xb = t.t[1].x; yb = t.t[1].y;
	xc = t.t[2].x; yc = t.t[2].y;
	c1 = (xa * xa + ya * ya - xb * xb - yb * yb) / 2;
	c2 = (xa * xa + ya * ya - xc * xc - yc * yc) / 2;
	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;
}
TCircle MinCircle2(int tce, TTriangle ce)
{
	TCircle tmp;
	if (tce == 0) tmp.r = -2;
	else if (tce == 1)
	{
		tmp.centre = ce.t[0];
		tmp.r = 0;
	}
	else if (tce == 2)
	{
		tmp.r = distance(ce.t[0], ce.t[1]) / 2;
		tmp.centre.x = (ce.t[0].x + ce.t[1].x) / 2;
		tmp.centre.y = (ce.t[0].y + ce.t[1].y) / 2;
	}
	else if (tce == 3) tmp = circumcirleOfTriangle(ce);
	return tmp;
}
void Mincircle1(int t, int tce, TTriangle ce)
{
	int i, j;
	TPoint tmp;
	c = MinCircle2(tce, ce);
	if (tce == 3) return ;
	for (int i = 1; i <= t; i++)
	{
		if (distance(a[i], c.centre) > c.r)
		{
			ce.t[tce] = a[i];
			Mincircle1(i - 1, tce + 1, ce);
			tmp = a[i];
			for (int j = i; j >= 2; j--)
			{
				a[j] = a[j - 1];
			}
			a[1] = tmp;
		}
	}
}
void run(int n)
{
	TTriangle ce;
	int i;
	Mincircle1(n, 0, ce);
	printf("%.2lf %.2lf %.2lf\n", c.centre.x, c.centre.y, c.r);
}
int main()
{
	int n;
	while (scanf("%d", &n) != EOF && n)
	{
		for (int i = 1; i <= n; i++)
			scanf("%lf%lf", &a[i].x, &a[i].y);
		run(n);
	}
}


给出n个点,求这n个点的最小覆盖圆

显然mincircle可以由A边界上的最多三个点圈定,也就是说,存在一个点集B,B的绝对值小于等于三,mincircleB = mincircleA 所以如果a 不属于b 则mincircle (A-‘a') = mincircle(A) 如果mincircle(A-’a') 不等于mincircleA 则a属于b ,因此,可以从一个空集开始,不断把点集加入,同时维护外接圆最小即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值