最小圆覆盖

粘个模版。。。

#include <stdio.h>
#include <math.h>

const int maxn = 1005;
const double eps = 1e-8;
struct TPoint {
    double x, y;
    TPoint operator-(TPoint & a) {
        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 dist(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 circumcircleOfTriangle(TTriangle t) {
    //三角形的外接圆
    TCircle tmp;
    double a, b, c, c1, c2;
    double xA, yA, xB, yB, xC, yC;
    a = dist(t.t[0], t.t[1]);
    b = dist(t.t[1], t.t[2]);
    c = dist(t.t[2], t.t[0]);
    //根据S = a * b * c / R / 4;求半径R
    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 = dist(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 = circumcircleOfTriangle(ce);
    return tmp;
}

void MinCircle(int t, int tce, TTriangle ce) {
    int i, j;
    TPoint tmp;
    c = MinCircle2(tce, ce);
    if (tce == 3) return;
    for (i = 1; i <= t; i++) {
        if (dist(a[i], c.centre) > c.r) {
            ce.t[tce] = a[i];
            MinCircle(i - 1, tce + 1, ce);
            tmp = a[i];
            for (j = i; j >= 2; j--) {
                a[j] = a[j - 1];
            }
            a[1] = tmp;
        }
    }
}

int main() 
{
    int n,i;
    TPoint op;
    int cas=1;
    int t;
    scanf("%d",&t);
    while (t--) 
    {
        scanf("%d",&n);
        for (i = 1; i <= n; i++)
            scanf("%lf%lf", &a[i].x, &a[i].y);
        TTriangle ce;
        MinCircle(n, 0, ce);
        printf("%.2lf %.2lf %.2lf\n", c.centre.x, c.centre.y, c.r);    
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值