hdu 3007 最小包围圆

来源:互联网 发布:哈尔滨淘宝何时停运 编辑:程序博客网 时间:2024/05/02 04:49

求能包含n个点的最小圆。参考了好多代码,被一个外心的公式坑了半天。。。

最后还是用有精度损失的方程去解...好像也就那个了...

话说据说求两点间最大距离就行了,数据实在水 = =

代码:

/**  Author:      illuz <iilluzen[at]gmail.com>*  Blog:        http://blog.csdn.net/hcbbt*  File:        zoj1450.cpp*  Create Date: 2013-11-21 20:14:57*  Descripton:  minCircle, geometric */#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;#define sqr(a) ((a) * (a))const int MAXN = 1010;const double PI = 2.0 * asin(1.0);const double EPS = 1e-6;const double INF = 1e20;struct Point {    double x;    double y;    Point() {};    Point(double tx, double ty) {        x = tx;        y = ty;    }    Point operator-(const Point &b) const {        return Point(x - b.x, y - b.y);    }    Point operator+(const Point &b) const {        return Point(x + b.x, y + b.y);     }    Point operator*(const double &k) const {        return Point(x * k, y * k);    }    double operator*(const Point &b) const {    // 点积        return x * b.y + y * b.x;    }    double operator^(const Point &b) const {    // 叉积        return x * b.y - y * b.x;    }} p[MAXN];typedef Point Vector;struct Triangle {    Point t[3];    Triangle() { }    Triangle(const Point a, const Point b, const Point c) {        t[0] = a;        t[1] = b;        t[2] = c;    }};struct Circle {    Point cent;    double r;    Circle() { }    Circle(Point p, double d) {        cent = p;        r = d;    }};double dis(const Point &a, const Point &b) {    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));}//double cross(const Point &a, const Point &b, const Point &o) {//    return (a.x - o.x) * (b.y - o.y) - (b.x - o.x) * (a.y - o.y);//}double triangleS(Triangle t) {    return (t.t[1] - t.t[0]) * (t.t[2] - t.t[0]);}double ddis(const Point &a, const Point &b) {    return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);}Point midPoint(const Point &a, const Point &b) {    return Point((a.x + b.x) / 2.0, (a.y + b.y) / 2.0);}Point lxl(const Point &a, const Point &b, const Point &c, const Point &d) {    double k = ((a - c) ^ (c - d)) / ((a - b) ^ (c - d));    Point l = b - a;    return Point(a.x + l.x * k, a.y + l.y * k);}Point centerOfTriangle(Triangle t) {    Point a = midPoint(t.t[0], t.t[1]), b, c = midPoint(t.t[0], t.t[2]), d;    b = Point(a.x - t.t[0].y + t.t[1].y, a.y + t.t[0].x - t.t[1].x);    d = Point(c.x - t.t[0].y + t.t[2].y, c.y + t.t[0].x - t.t[2].x);    return lxl(a, b, c, d);}// Min Circle Of PointsCircle c;void minCircleWith2Points(int pi, int pj, const Point t[]) {    c.cent = midPoint(t[pi], t[pj]);    c.r = dis(t[pi], t[pj]) / 2.0;    for (int k = 0; k < pj; k++) {        if (dis(c.cent, t[k]) <= c.r) continue;        // if 3 point in line        if (fabs((t[pi] - t[pj]) ^ (t[k] - t[pj])) < EPS) {            double d1 = dis(t[pi], t[pj]);            double d2 = dis(t[pi], t[k]);            double d3 = dis(t[pj], t[k]);            if (d2 >= d3) {                c.cent = midPoint(t[pi], t[k]);                c.r = dis(t[pi], t[k]);            } else {                c.cent = midPoint(t[pj], t[k]);                c.r = dis(t[pj], t[k]);            }        } else {            c.cent = centerOfTriangle(Triangle(t[pi], t[pj], t[k]));            c.r = dis(c.cent, t[pi]);        }    }}void minCircleWith1Point(int pi, const Point t[]) {    c.cent = midPoint(t[0], t[pi]);    c.r = dis(t[0], t[pi]) / 2.0;    for (int j = 1; j < pi; j++)        if (dis(c.cent, t[j]) > c.r)            minCircleWith2Points(pi, j, t);}void minCircle(int n, const Point t[]) {    // init circle can be the convex hull diameter    c.cent = midPoint(t[0], t[1]);    c.r = dis(t[0], t[1]) / 2.0;    for (int i = 2; i < n; i++)        if (dis(c.cent, t[i]) > c.r)            minCircleWith1Point(i, t);}int main() {    int n;    while (~scanf("%d", &n) && n) {        for (int i = 0; i < n; i++)            scanf("%lf%lf", &p[i].x, &p[i].y);        if (n == 1) {            printf("%.2f %.2f 0.00\n", p[0].x, p[0].y);            continue;        }        minCircle(n, p);        printf("%.2f %.2f %.2f\n", c.cent.x, c.cent.y, c.r);    }    return 0;}


原创粉丝点击