zoukankan      html  css  js  c++  java
  • [CodeForces]1059D Nature Reserve

    大意:给你一个平面上N(N<=100000)个点,问相切于x轴的圆,将所有的点都覆盖的最小半径是多少。

    计算几何???Div2的D题就考计算几何???某人昨天上课才和我们说这种计算几何题看见就溜。。。。

    打完比赛才发现好像并不用计算几何,实则是一个二分答案的水题。。

    发现如果点在x轴两侧就肯定不行,所以我们把所有的点都挪到一侧。

    我们二分一个半径,然后发现因为圆相切于x轴,那么这个圆的圆心一定在y=r的直线上移动。

    对于所有的点,它可以被如图的线段AC上的点覆盖,点在AC下方也同理。(终于有个图是我自己画的了。。。)

    然后发现圆心的取值就在xi±√(R2-(R-yi)2)之间。

    所以说把每个点的可取圆心的点的集合的交算出来,看看是不是空集,不是空集就可行。

    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <cstdio>
    using namespace std;
    const double eps=1e-8;
    int n;
    struct Node {int x,y;}node[100005];
    bool flag;
    bool ck(double mid) {
        double l=-1e18,r=1e18;
        for(int i=1;i<=n;i++) {
            if(node[i].y>mid+mid) return 0;
            double range=sqrt(node[i].y*(2*mid-node[i].y));
            l=max(l,node[i].x-range);r=min(r,node[i].x+range);
        }
        return (l-r+eps)<=0;
    }
    int main() {
        scanf("%d",&n);
        scanf("%d%d",&node[1].x,&node[1].y);
        if(node[1].y<0) flag=1;node[1].y=abs(node[1].y);
        for(int i=2;i<=n;i++) {
            scanf("%d%d",&node[i].x,&node[i].y);
            if(flag&&node[i].y>0){puts("-1") ;return 0;}
            if(flag==false && node[i].y<0) {puts("-1");return 0;}
            node[i].y=abs(node[i].y);
        }
        double l=0,r=1e18;int cnt=300;
        while(cnt--) {
            double mid=(l+r)/2;
            if(ck(mid)) r=mid;
            else l=mid;
        }
        printf("%lf",l);
    }
    Nature Reserve
    我是咸鱼。转载博客请征得博主同意Orz
  • 相关阅读:
    一题多解(六)—— 一个数二进制形式 1 的个数
    心算技巧
    心算技巧
    位运算应用及其注意事项
    位运算应用及其注意事项
    辨异 —— 不同的编程语言(编译型语言、解释型语言、动态语言、静态语言)
    C#POP3协议实现SSL验证登陆GMAIL
    PB学习笔记(一)
    24点计算 --- 庞果
    JAVA网站高并发解决方案
  • 原文地址:https://www.cnblogs.com/sdfzhsz/p/9748360.html
Copyright © 2011-2022 走看看