zoukankan      html  css  js  c++  java
  • 计算几何——圆卡精度cf1059D

    double 在1e17以后就不能顾及小数,所以用一下加精度的技巧

    sqrt(r*r-d*d)=sqrt(r+d)*sqrt(r-d)

    遇到误差在几位以内的注意要修改二分的精度,用最大的数据去乘以精度即可

    #include<bits/stdc++.h>
    using namespace std;
    
    const double esp = 1e-7;
    const double inf = 1e14;
    
    double sgn(double x){
        if(fabs(x)<esp)return 0;
        if(x<0)return -1;
        return 1;
    }
    struct Point {
        double x,y;
        Point(){}
        Point (double x,double y):x(x),y(y){}
        double distance(Point p){
            return hypot(x-p.x,y-p.y);
        }
    };
    struct circle{
        Point p;
        double r;
        circle(){}
        circle(Point p,double r):p(p),r(r){}
        int relation(Point b){
            double dst=b.distance(p);
            if(sgn(dst-r)<0)return 2;
            else if(sgn(dst-r)==0)return 1;
            return 0;
        }
        int relationline(double y){//直线只有y=b 
            double dst=fabs(y-p.y);
            if(sgn(dst-r)<0)return 2;
            else if(sgn(dst-r)==0)return 1;
            return 0;
        }
        int pointcrossline(double y,Point &p1,Point &p2){
            if(!(*this).relationline(y))return 0;
            Point a=Point(p.x,y);
            double d=fabs(p.y-y);
            d=sqrt(r*r-d*d);
            if(sgn(d)==0){
                p1=a,p2=a;
                return 1;
            }
            p1=Point(a.x-d,y);
            p2=Point(a.x+d,y);
            return 2;
        }
    };
    
    #define maxn 100005
    Point p[maxn];
    int n;
    
    //判断半径r是否可行,每个点画个圆和y=r相交,维护L,R即可 
    int judge(long double r){
        long double L=-1e15,R=1e15;
        
        for(int i=1;i<=n;i++){
            if(r*2-p[i].y<0)return 0; 
            long double d=fabs(r-p[i].y);
            d=sqrt(r+d)*sqrt(r-d);//这里要扩大精度 
            L=max(L,p[i].x-d);R=min(R,p[i].x+d);    
        }
        return L<=R;
    }
    
    int main(){
        cin>>n;
        int flag0=0,flag1=0;
        double Min=inf,Max=-inf,M=-inf;
        for(int i=1;i<=n;i++){ 
            scanf("%lf%lf",&p[i].x,&p[i].y);
            if(p[i].y<0) flag0=1;
            else flag1=1;
            Min=min(Min,p[i].x);Max=max(Max,p[i].x);
            M=max(M,fabs(p[i].y));
        }    
        if(flag0 && flag1){puts("-1");return 0;}
        if(flag0){
            for(int i=1;i<=n;i++)
                p[i].y *= -1;
        }
        
        double l=0,r=inf,mid,ans=-1,x=max((Max-Min),M)*esp;
        while(x<r-l){
            mid=(l+r)/2;
            if(judge(mid))
                ans=mid,r=mid;
            else l=mid;
        }
        printf("%.7lf",ans);
    }
  • 相关阅读:
    Dynamics AX
    专注于领域驱动设计的研究与实践系列转载
    在C#里使用属性,如Obsolete,Serializable,XmlRoot
    SQL 2005 with(nolock)详解
    Microsoft Domain Oriented NLayered .NET 4.0 App Sample (DDD Architecture)
    使用 .NET4 中的Task优化线程池【.NET4 多核并行】
    实现简单DTO适配器,解放你的双手
    最强悍的VS插件—reSharper
    通过代码配置 Log4net
    Microsoft NLayerApp案例理论与实践–DDD、分布式DDD及其分层【转】
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10948915.html
Copyright © 2011-2022 走看看