最小圆覆盖——模板题

来源:互联网 发布:竞品分析ppt模板 知乎 编辑:程序博客网 时间:2024/05/21 14:45
#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 ,因此,可以从一个空集开始,不断把点集加入,同时维护外接圆最小即可

0 0
原创粉丝点击