CF 8D Two Friends 【二分+三分】

来源:互联网 发布:帝国cms 栏目别名 编辑:程序博客网 时间:2024/05/16 16:02

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

判断一下两个人能否一起到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-6struct 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\n", 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\n", ans);    return 0;}