zoukankan      html  css  js  c++  java
  • [日常摸鱼]bzoj2823 [AHOI2012]信号塔

    题意:$n$个点,求最小圆覆盖,$n leq 5e5$


    这题数据是随机的hhh

    我们可以先求出凸包然后对凸包上的点求最小圆覆盖…(不过直接求应该也行?)

    反正随便写好像都能过…

    #include<cstdio>
    #include<algorithm>
    #include<cstdlib>
    #include<cmath>
    using namespace std;
    const int N=500005;
    struct Point
    {
        double x,y;
        int rnd;
        Point(double x=0,double y=0):x(x),y(y){}
    }p[N],s[N];
    struct Line
    {
        double k,b;
    };
    inline bool cmp1(Point a,Point b)
    {
        if(a.x==b.x)return a.y<b.y;
        return a.x<b.x;
    }
    inline bool cmp2(Point a,Point b)
    {
        return a.rnd<b.rnd;
    }
    inline Point operator +(Point a,Point b)
    {
        return Point(a.x+b.x,a.y+b.y);
    }
    inline Point operator -(Point a,Point b)
    {
        return Point(a.x-b.x,a.y-b.y);
    }
    
    inline Point operator /(Point a,double d)
    {
        return Point(a.x/d,a.y/d);
    }
    inline double cross(Point a,Point b)
    {
        return a.x*b.y-a.y*b.x;
    }
    inline double sqr2(double x)
    {
        return x*x;
    }
    inline double dist(Point a,Point b)
    {
        return sqrt(sqr2(a.x-b.x)+sqr2(a.y-b.y));
    }
    inline Line getLine(double k,Point a)
    {
        Line res;res.k=k;
        res.b=a.y-a.x*k;
        return res;
    }
    inline Point getLineIntersection(Line l1,Line l2)
    {
        Point res;
        res.x=(l2.b-l1.b)/(l1.k-l2.k);
        res.y=res.x*l1.k+l1.b;
        return res;
    }
    inline Point getCircle(Point a,Point b,Point c)
    {
        Point p1=(a+b)/2,p2=(a+c)/2;
        double k1=-(b.x-a.x)/(b.y-a.y);
        double k2=-(c.x-a.x)/(c.y-a.y);
        Line l1=getLine(k1,p1),l2=getLine(k2,p2);
        return getLineIntersection(l1,l2); 
    }
    inline Point minCircle(double &r,int n)
    {
        for(register int i=1;i<=n;i++)s[i].rnd=rand(); 
        sort(s+1,s+n+1,cmp2);
        Point o=s[1];r=0;
        for(register int i=2;i<=n;i++)if(r<dist(o,s[i]))
        {
            o=s[i];r=0;
            for(register int j=1;j<i;j++)if(r<dist(o,s[j]))
            {
                o=(s[i]+s[j])/2;
                r=dist(o,s[i]);
                for(register int k=1;k<j;k++)if(r<dist(o,s[k]))
                {
                    o=getCircle(s[i],s[j],s[k]);
                    r=dist(o,s[i]);
                }
            }
        }
        return o;
    }
    inline int convexHull(int n)
    {
        sort(p+1,p+n+1,cmp1);
        int t=0,k;
        for(register int i=1;i<=n;i++)
        {
            while(t>1&&cross(s[t]-s[t-1],p[i]-s[t-1])<0)t--;
            s[++t]=p[i];
        }
        k=t;
        for(register int i=n-1;i>=1;i--)
        {
            while(t>k&&cross(s[t]-s[t-1],p[i]-s[t-1])<0)t--;
            s[++t]=p[i];
        }
        if(n>1)t--;
        return t;
    }
    int main()
    {
        int n;scanf("%d",&n);
        for(register int i=1;i<=n;i++)scanf("%lf%lf",&p[i].x,&p[i].y);
        int t=convexHull(n);double r;
        Point res=minCircle(r,t);
        printf("%.2lf %.2lf %.2lf",res.x,res.y,r);
        return 0;
    }
  • 相关阅读:
    Leetcode题目practice
    文件操作
    39个奇葩代码注释,拿走不谢
    Spring Boot 之配置导入,强大到不行!
    Git 的这个神技,学会爽歪歪~
    同事天天写垃圾代码,就没办法?
    for (;;) 与 while (true),哪个更快?
    Spring Boot 怎么打一个可执行 Jar 包?
    程序员真的是太太太太太太太太难了!
    面试官:new一个对象有哪两个过程?
  • 原文地址:https://www.cnblogs.com/yoshinow2001/p/8318630.html
Copyright © 2011-2022 走看看