BZOJ 2823 [AHOI2012]信号塔 (最小圆覆盖学习笔记)

最小圆覆盖的模板题。

只记得这么做是期望O(n)的了qwq,证明不太记得了,忘了可以看看这个:http://www.cnblogs.com/DaD3zZ-Beyonder/p/5674663.html

找到的重心的计算公式如下:

重心的计算公式

#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
const double eps=1e-9;
struct point {
    double x,y;
};
double dis(point p1,point p2) {
    double dx=p1.x-p2.x,dy=p1.y-p2.y;
    return sqrt(dx*dx+dy*dy);
}
int n;
point a[1000005],o;
double r;
inline double dot(point p){return p.x*p.x+p.y*p.y;}

void circum(point p1,point p2,point p3) {
    double
        a=2*(p2.x-p1.x),
        b=2*(p2.y-p1.y),
        c=dot(p2)-dot(p1),
        d=2*(p3.x-p1.x),
        e=2*(p3.y-p1.y),
        f=dot(p3)-dot(p1);

    double k=b*d-e*a;
    o.x=(b*f-e*c)/k;
    o.y=(d*c-a*f)/k;
    r=dis(p1,o);
}
int main() 
{
    scanf("%d",&n);
    for(int i=1; i<=n; i++)
        scanf("%lf%lf",&a[i].x,&a[i].y);

    random_shuffle(a+1,a+n+1);

    o=a[1],r=0;
    for(int i=2; i<=n; i++)
        if(dis(o,a[i])>r+eps) 
        {
            o=a[i];r=0;
            for(int j=1; j<=i-1; j++)
                if(dis(o,a[j])>r+eps) 
                {
                    o.x=(a[i].x+a[j].x)/2;
                    o.y=(a[i].y+a[j].y)/2;
                    r=dis(o,a[j]);
                    for(int k=1; k<=j-1; k++)
                        if(dis(o,a[k])>r+eps)
                            circum(a[i],a[j],a[k]);
                }
        }
    printf("%.2lf %.2lf %.2lf\n",o.x,o.y,r);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值