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;
    }
    
  • 相关阅读:
    C#微信开发文档
    XML相关操作
    css基本样式总结
    CSS选择器及其优先级
    Java学习之路(七)
    G2( bizCharts ) React 绘制混合图例
    G2 绘制混合图例 demo
    python 前后端分离 简单的数据库返回接口
    nginx 跨域
    react-router-dom
  • 原文地址:https://www.cnblogs.com/nofind/p/12212520.html
Copyright © 2011-2022 走看看