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

    bzoj 1337 最小圆覆盖

    • 补充一个求三角形外心的向量法.用了点积的几何意义,很实用.出处.

      向量法求外心

    • 使用随机增量法求.首先随机打乱顺序,然后三重循环,选择当前在圆外的点更新圆,分别按照 (1/2/3) 个点确定圆的方式更新即可.

    • 由于随机一个点不在前 (i) 个点的最小覆盖圆内的概率是 (frac 3 i) ,可以证明这样的时间复杂度是 (O(n)) 的,这种做法可以推广到常数维度上,时间复杂度仍为 (O(n)) .

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define mp make_pair
    #define pii pair<int,int>
    inline int read()
    {
    	int x=0;
    	bool pos=1;
    	char ch=getchar();
    	for(;!isdigit(ch);ch=getchar())
    		if(ch=='-')
    			pos=0;
    	for(;isdigit(ch);ch=getchar())
    		x=x*10+ch-'0';
    	return pos?x:-x;
    }
    const double eps=1e-9;
    const int MAXN=1e5+10;
    int dcmp(double x)
    {
    	return fabs(x)<=eps?0:(x>0?1:-1);
    }
    struct v2{
    	double x,y;
    	v2(double x=0,double y=0):x(x),y(y) {}
    	v2 operator + (const v2 &rhs) const
    		{
    			return v2(x+rhs.x,y+rhs.y);
    		}
    	v2 operator / (const double &rhs) const
    		{
    			return v2(x/rhs,y/rhs);
    		}
    	v2 operator - (const v2 &rhs) const
    		{
    			return v2(x-rhs.x,y-rhs.y);
    		}
    	double operator * (const v2 &rhs) const
    		{
    			return x*rhs.y-y*rhs.x;
    		}
    	double modulus()
    		{
    			return sqrt(x*x+y*y);
    		}
    };
    double dist(v2 a,v2 b)
    {
    	return (a-b).modulus();
    }
    v2 CirCentre(v2 a,v2 b,v2 c)
    {
    	v2 centre;
    	double a1=b.x-a.x;
    	double b1=b.y-a.y;
    	double c1=(a1*a1+b1*b1)/2.0;
    	double a2=c.x-a.x;
    	double b2=c.y-a.y;
    	double c2=(a2*a2+b2*b2)/2.0;
    	double d=a1*b2-a2*b1;
    	centre.x=a.x+(c1*b2-c2*b1)/d;
    	centre.y=a.y+(a1*c2-a2*c1)/d;
    	return centre;
    }
    bool incircle(v2 p,v2 centre,double r)
    {
    	return dcmp(dist(p,centre)-r)<=0;
    }
    void MinCircleCover(v2 *p,int n,v2 &centre,double &r)
    {
    	srand(time(NULL));
    	random_shuffle(p+1,p+1+n);
    	centre=p[1];
    	r=0;
    	for(int i=2;i<=n;++i)
    		{
    			if(!incircle(p[i],centre,r))
    				{
    					centre=p[i];
    					r=0;
    					for(int j=1;j<i;++j)
    						{
    							if(!incircle(p[j],centre,r))
    								{
    									centre=(p[i]+p[j])/2.0;
    									r=(p[i]-p[j]).modulus()/2.0;
    									for(int k=1;k<j;++k)
    										{
    											if(!incircle(p[k],centre,r))
    												{
    													centre=CirCentre(p[i],p[j],p[k]);
    													r=dist(centre,p[i]);
    												}	
    										}
    								}
    						}
    				}
    		}
    }
    int n;
    v2 p[MAXN];
    int main()
    {
    	n=read();
    	for(int i=1;i<=n;++i)
    		scanf("%lf%lf",&p[i].x,&p[i].y);
    	v2 centre;
    	double r;
    	MinCircleCover(p,n,centre,r);
    	printf("%.3lf
    ",r);
    	return 0;
    }
    
  • 相关阅读:
    以查询功能谈下,三层架构中的工厂模式与其中反射的应用
    结对编程
    第四周周结
    知识思考
    自我介绍
    本周开发工作及内容
    第三周周结
    启航
    如何写出健壮的Java代码
    CentOS x64上Matlab R2015b的镜像安装方法与卸载
  • 原文地址:https://www.cnblogs.com/jklover/p/10388841.html
Copyright © 2011-2022 走看看