Loading

[模板] 最小圆覆盖 求三角形外心 ZOJ-1450

[模板] 最小圆覆盖 求三角形外心 ZOJ-1450

利用随机函数把理论复杂度降到n

代码

struct Point {
    double x, y;
};

Point p[500005];
Point o;
int n;
double ri;

double dis(Point a, Point b) {
    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}

void tt(Point p1, Point p2, Point p3) {
    double a, b, c, d, e, f;
    a = p2.y - p1.y;
    b = p3.y - p1.y;
    c = p2.x - p1.x;
    d = p3.x - p1.x;
    f = p3.x * p3.x + p3.y * p3.y - p1.x * p1.x - p1.y * p1.y;
    e = p2.x * p2.x + p2.y * p2.y - p1.x * p1.x - p1.y * p1.y;
    o.x = (a * f - b * e) / (2 * a * d - 2 * b * c);
    o.y = (d * e - c * f) / (2 * a * d - 2 * b * c);
    ri = dis(o, p1);
}

int main() {
    while (scanf("%d", &n), n) {
        for (int i = 1; i <= n; i++) scanf("%lf%lf", &p[i].x, &p[i].y);
        random_shuffle(p + 1, p + 1 + n);
        o = p[1];
        ri = 0;
        for (int i = 2; i <= n; i++) {
            if (dis(p[i], o) > ri + eps) {
                o = p[i], ri = 0;
                for (int j = 1; j <= i - 1; j++) {
                    if (dis(o, p[j]) > ri + eps) {
                        o.x = (p[i].x + p[j].x) / 2;
                        o.y = (p[i].y + p[j].y) / 2;
                        ri = dis(o, p[j]);
                        for (int k = 1; k <= j - 1; k++)
                            if (dis(o, p[k]) > ri + eps) tt(p[i], p[j], p[k]);
                    }
                }
            }
        }
        printf("%.2f %.2f %.2f\n", o.x, o.y, ri);
    }
}
posted @ 2020-08-30 19:44  MQFLLY  阅读(125)  评论(0编辑  收藏  举报