zoukankan      html  css  js  c++  java
  • [CF1059D] Nature Reserve

    Description

    (N) 个点,求与 (y=0) 相切的,包含这 (N) 个点的最小圆的半径。

    Solution

    考虑二分半径,现在要检验 (r) 是否可行,显然对于每个 ((x_i,y_i)) 我们可以计算出 (d=sqrt {r^2 - (y_i-r)^2}),则区间 ([x_i-d, x_i+d]) 是可行的,我们只需要验证所有区间是否有交即可。

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long 
    const int N = 100005;
    
    struct point 
    {
        double x,y;
    } p[N];
    
    int n;
    
    bool check(double r)
    {
        double mn=1e38,mx=-1e38;
        for(int i=1;i<=n;i++)
        {
            if(r*r-(p[i].y-r)*(p[i].y-r)<-1e-9) return false;
            double d=sqrt(r*r-(p[i].y-r)*(p[i].y-r));
            mn=min(mn,p[i].x+d);
            mx=max(mx,p[i].x-d);
        }
        return mn-mx>=-1e-9;
    }
    
    signed main()
    {
        cin>>n;
        for(int i=1;i<=n;i++) cin>>p[i].x>>p[i].y;
        double mx=0;
        for(int i=1;i<=n;i++) mx=max(mx,max(abs(p[i].x),abs(p[i].y)));
        double ymn=1e18,ymx=-1e18;
        for(int i=1;i<=n;i++) ymn=min(ymn,p[i].y), ymx=max(ymx,p[i].y);
        if(ymn<0 && ymx>0) 
        {
            cout<<-1<<endl;
            return 0;
        }
        for(int i=1;i<=n;i++) p[i].y=abs(p[i].y);
        double l=0,r=mx*mx*10;
        while(r-l>1e-8 && (r-l)/r>1e-10)
        {
            double mid=(l+r)/2;
            // cout<<"mid="<<mid<<endl;
            if(check(mid)) r=mid;
            else l=mid;
        }
        if(r>mx*mx*5)
        {
            cout<<-1<<endl;
        }
        else 
        {
            printf("%.10lf
    ",r);
        }
    }
    
  • 相关阅读:
    搜狗搜索用户体验
    第六周学习进度条
    对我们团队NBPL的改进方案意见
    钱多多软件制作第七天
    团队冲刺第二周05
    团队冲刺第二周04
    团队冲刺第二周03
    输入法评价
    团队冲刺第二周02
    团队冲刺第二周01
  • 原文地址:https://www.cnblogs.com/mollnn/p/13996790.html
Copyright © 2011-2022 走看看