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

    题意

    简单说一下做法,并不知道怎么证明:

    假设当前求出了([1,i-1])的最小覆盖圆,现在考虑([1,i])的最小覆盖圆:
    如果(i)在当前圆中就不必改动。
    不然(i)必定在圆上,我们令圆心为(i),半径为(0)
    现在固定了一个点,我们枚举(jin[1,i-1]),如果(j)不在当前圆中,我们固定(j)
    现在固定了两个点,我们枚举(kin[1,j-1]),如果(k)不在当前圆中,就固定(k),现在固定了三个点,可以求出圆。

    复杂度:期望(O(n))很假的样子,但就是真的。

    固定三个点求圆:从两条弦做中垂线求交点便是圆心。

    code:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=100010;
    const double eps=1e-12;
    const double Pi=acos(-1.0);
    int n;
    struct Point
    {
        double x,y;
        inline double len(){return x*x+y*y;}
        Point operator+(const Point a)const{return (Point){x+a.x,y+a.y};}
        Point operator-(const Point a)const{return (Point){x-a.x,y-a.y};}
        Point operator*(const double k){return (Point){x*k,y*k};}
        Point operator/(const double k){return (Point){x/k,y/k};}
        double operator*(const Point a)const{return x*a.y-y*a.x;}
        double operator&(const Point a)const{return x*a.x+y*a.y;}
    }p[maxn];
    inline int dcmp(double x)
    {
    	if(fabs(x)<=eps)return 0;
    	return x<0?-1:1;
    }
    struct Line{Point p,v;};
    inline Point turn(Point a,double theta)
    {
    	return (Point){a.x*cos(theta)-a.y*sin(theta),a.x*sin(theta)+a.y*cos(theta)};
    } 
    inline Point get(Point a,Point b){return b-a;}
    inline Point getpoint(Line a,Line b)
    {
        Point p1=a.p,p2=b.p,v1=a.v,v2=b.v;
        Point u=get(p1,p2);
        Point res=p1+v1*((u*v2)/(v1*v2));
        return res;
    }
    inline Point find_circle(Point a,Point b,Point c)
    {
    	return getpoint((Line){(a+b)/2.0,turn(get(a,b),Pi/2.0)},(Line){(a+c)/2.0,turn(get(a,c),Pi/2.0)});
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)scanf("%lf%lf",&p[i].x,&p[i].y);
    	random_shuffle(p+1,p+n+1);
    	Point now=(Point){0,0};double nowr=0;
    	for(int i=1;i<=n;i++)
    	{
    		if(dcmp(get(now,p[i]).len()-nowr)<=0)continue;
    		now=p[i],nowr=0;
    		for(int j=1;j<i;j++)
    		{
    			if(dcmp(get(now,p[j]).len()-nowr)<=0)continue;
    			now=(p[i]+p[j])/2.0;nowr=get(now,p[j]).len();
    			for(int k=1;k<j;k++)
    			{
    				if(dcmp(get(now,p[k]).len()-nowr)<=0)continue;
    				now=find_circle(p[i],p[j],p[k]);nowr=get(now,p[k]).len();
    			}
    		}
    	}
    	printf("%.10lf
    %.10lf %.10lf",sqrt(nowr),now.x,now.y);
    	return 0;
    }
    
  • 相关阅读:
    loaded some nib but the view outlet was not set
    指标评比
    IOS DEVELOP FOR DUMMIES
    软件测试题二
    javascript select
    DOM节点类型详解
    mysql操作
    UVA 10055
    solutions for 'No Suitable Driver Found For Jdbc'
    解决git中文乱码问题
  • 原文地址:https://www.cnblogs.com/nofind/p/12212520.html
Copyright © 2011-2022 走看看