bzoj1336/1337/2823 最小圆覆盖 计算几何

来源:互联网 发布:vs2017 连接mysql 编辑:程序博客网 时间:2024/04/30 01:55

随机增量法太神,由于圆覆盖的话一次能够去很多点,我们为了防止最坏的情况发生,我们可以把数据随机一下,这样就把复杂度降到了期望nlogn 的复杂度。

具体正面自行百度。

注意每个题的输出格式 本码是1336的码。

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;#define eps 1e-8#define maxn 510000struct node{    double x,y;}p[maxn],o;int n;double r;double sqr(double x){    return x*x;}double dis(node a,node b){    return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));}node getcen(node a,node b){    return (node){(a.x+b.x)/2,(a.y+b.y)/2};}node getcen(node a,node b,node c){    double k1,k2,b1,b2;    node p1,p2,p3;    p1=getcen(a,b);    k1=-1*(a.x-b.x)/(a.y-b.y);    b1=p1.y-k1*p1.x;    p2=getcen(b,c);    k2=-1*(c.x-b.x)/(c.y-b.y);    b2=p2.y-k2*p2.x;    if(b1==b2)    {        double maxs=0;        if(maxs<dis(a,b))        {            maxs=dis(a,b);            p3=getcen(a,b);        }        if(maxs<dis(a,c))        {            maxs=dis(a,c);            p3=getcen(a,c);        }        if(maxs<dis(c,b))        {            maxs=dis(c,b);            p3=getcen(c,b);        }    }    else    {        p3.x=(b1-b2)/(k2-k1);        p3.y=k1*p3.x+b1;    }    return p3;}int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++)    {        scanf("%lf%lf",&p[i].x,&p[i].y);        swap(p[i],p[rand()%i+1]);    }    o=p[1];    for(int i=1;i<=n;i++)    {        if(dis(o,p[i])<=r+eps) continue;        o=getcen(p[1],p[i]);r=dis(p[i],o);        for(int j=1;j<i;j++)        {            if(dis(o,p[j])<=r+eps)continue;            o=getcen(p[i],p[j]);r=dis(p[i],o);            for(int k=1;k<j;k++)            {                if(dis(o,p[k])<=r+eps)continue;                o=getcen(p[i],p[j],p[k]);r=dis(p[i],o);            }        }    }    printf("%.10lf\n",r);    printf("%.10lf %.10lf\n",o.x,o.y);    return 0;}

0 0
原创粉丝点击