zoukankan      html  css  js  c++  java
  • CF 8D Two Friends 【二分+三分】

    三个地点构成一个三角形。

    判断一下两个人能否一起到shop然后回家,如果不能:

    两个人一定在三角形内部某一点分开,假设沿着直线走,可以将问题简化。

    三分从电影院出来时候的角度,在对应的直线上二分出一个分离点即可。

    三分角度的方法:在shop和home两个点之间找一个点p,链接p和电影院,在这个线段上面二分出分离点。



    注意:精度。


    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    #define sqr(x) ((x)*(x))
    #define eps 1e-6
    
    struct POINT {
        double x, y;
        POINT() {}
        POINT(double _x, double _y): x(_x), y(_y) {}
    } c, s, h;
    double t1, t2;
    
    double dist(POINT &x, POINT &y) {
        return sqrt(sqr(x.x-y.x) + sqr(x.y-y.y));
    }
    double calc(double m) {
        POINT a = POINT(s.x*(1-m) + h.x*m, s.y*(1-m) + h.y*m);
        POINT b;
        double ac = dist(a, c);
        double ah = dist(a, h);
        double as = dist(s, a);
        if (ac + ah <= t2 && ac + as <= t1) {
            return min(t2-ah, t1-as);
        }
        double l = 0, r = 1, mid, la, lb, lc;
        for (int i=0; i<300; i++) {
            mid = (l + r)/2.0;
            b = POINT(c.x*(1-mid) + a.x*mid, c.y*(1-mid) + a.y*mid);
            la = dist(b, c);
            lb = dist(b, h);
            lc = dist(b, s);
            if (la+lb<=t2 && la+lc<=t1) l = mid;
            else r = mid;
        }
        b = POINT(c.x*(1-l) + a.x*l, c.y*(1-l) + a.y*l);
        return dist(b, c);
    }
    int main() {
    
        cin >>t1>>t2>>c.x>>c.y>>h.x >> h.y >> s.x>> s.y;
        double la, lb, lc;
        la = dist(c, s);
        lb = dist(c, h);
        lc = dist(s, h);
    
        if (lb + t2 >= la + lc) {
            printf("%.10lf
    ", min(lb+t2, la+lc+t1));
            return 0;
        }
        t1 += la + 1e-10;
        t2 += lb + 1e-10;
    
        double l = 0, r = 1, lm, rm, ans = 0, v1, v2;
        for (int i=0; i<300; i++) {
            lm = (2*l + r)/3.0, rm = (2*r + l)/3.0;
            v1 = calc(lm), v2 = calc(rm);
            ans = max(ans, max(v1, v2));
            if (v1 < v2) l = lm;
            else r = rm;
        }
    
        printf("%.10lf
    ", ans);
    
        return 0;
    }
    


  • 相关阅读:
    github 代理加速
    centos系统语言设置为中文
    红帽 / CentOS安装Jenkins
    查看api有没有更新到位
    永久关闭Windows10或Windows11的系统自动更新
    api传文件连接超时
    docker日常使用
    开发者工具批量替换
    Linux常用工具安装
    office密钥
  • 原文地址:https://www.cnblogs.com/aukle/p/3220213.html
Copyright © 2011-2022 走看看