zoukankan      html  css  js  c++  java
  • BZOJ1337 最小圆覆盖

    题目链接:戳我

    一个最小圆覆盖的模板题吧。。。

    最小圆覆盖怎么做??

    就是枚举三个点,第一个点做圆心,第二、三个点和第一个点联合起来确定一个圆。

    看起来是(O(n^3))的是不是?但是其实均摊时间复杂度是(O(n))的。具体为什么我也不会证,但是我们可以知道,如果枚举后面的点已经在前面确定好的圆里面就不需要再计算了是吧qwqwq

    对于三个点(x1,y1),(x2,y2),(x3,y3),和未知的圆心(x0,y0)

    对于三个点(x1,y1),(x2,y2),(x3,y3),和未知的圆心(x0,y0)

    (egin{cases}(x1-x0)^2+(y1-y0)^2=r^2\(x2-x0)^2+(y2-y0)^2=r^2\(x3-x0)^2+(y3-y0)^2=r^2end{cases})

    (egin{cases}(x2-x3)x0+(y2-y3)y0=frac{(x2^2-x3^2)+(y2^2-y3^2)}{2}\(x1-x2)x0+(y1-y2)y0=frac{(x1^2-x2^2)+(y1^2-y2^2)}{2}end{cases})

    (egin{cases}a*x0+b*y0=e\c*x0+d*y0=fend{cases})

    (egin{cases}x=frac{de-bf}{ad-bc};\y=frac{ce-af}{bc-ad};end{cases})

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<ctime>
    #define eps 1e-15
    #define MAXN 500010
    using namespace std;
    int n;
    double r;
    struct Node{double x,y;}node[MAXN],o;
    inline double dist(Node a,Node b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
    inline void solve(Node A,Node B,Node C)
    {
        double a=(B.x-C.x)*2;
        double b=(B.y-C.y)*2;
        double c=(A.x-B.x)*2;
        double d=(A.y-B.y)*2;
        double e=(B.x*B.x-C.x*C.x)+(B.y*B.y-C.y*C.y);
        double f=(A.x*A.x-B.x*B.x)+(A.y*A.y-B.y*B.y);
        o.x=(d*e-b*f)/(a*d-b*c);
        o.y=(c*e-a*f)/(b*c-a*d);
        r=dist(A,o);
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("ce.in","r",stdin);
        #endif
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%lf%lf",&node[i].x,&node[i].y);
        random_shuffle(&node[1],&node[n+1]);
        o=node[1]; r=0;
        for(int i=2;i<=n;i++)
            if(dist(node[i],o)>r+eps)
            {
                o=node[i];r=0;
                for(int j=1;j<i;j++)
                {
                    if(dist(node[j],o)>r+eps)
                    {
                        o.x=(node[i].x+node[j].x)/2;
                        o.y=(node[i].y+node[j].y)/2;
                        r=dist(o,node[j]);
                        for(int k=1;k<j;k++)
                            if(dist(node[k],o)>r+eps)
                                solve(node[i],node[j],node[k]);
                    }
                }
            }
        printf("%.3lf
    ",r);
    }
    
  • 相关阅读:
    如何用grep命令同时显示匹配行上下的n行 (美团面试题目)
    Maven面试宝典
    Java经典设计模式 总览
    Java设计模式之工厂模式
    Java设计模式
    三次握手,四次挥手 具体发送的报文和状态都要掌握(阿里)
    运动与饮食结合
    健身计划
    Java中的多线程=你只要看这一篇就够了
    js禁止复制粘贴
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10475211.html
Copyright © 2011-2022 走看看