Codeforces 8D Two Friends

来源:互联网 发布:淘宝网店货源供应商 编辑:程序博客网 时间:2024/06/06 03:58

【题意】有两个人AlanBob,他们现在都在A点,现在Bob想去B点,Alan想先到C点再去B点。Alan所走的总路程不能超过T1Bob所走的总路程不能超过T2。求他们从A出发到第一次分开所能走的最长的公共路程。

【解题方法】参考XHR神牛的论文AC。

【AC代码】

////Created by just_sort 2016/12/8//Copyright (c) 2016 just_sort.All Rights Reserved//#include <ext/pb_ds/assoc_container.hpp>#include <ext/pb_ds/tree_policy.hpp>#include <ext/pb_ds/hash_policy.hpp>#include <set>#include <map>#include <queue>#include <stack>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <sstream>#include <iostream>#include <algorithm>using namespace std;using namespace __gnu_pbds;typedef long long LL;typedef pair<int, LL> pp;#define MP(x,y) make_pair(x,y)const int maxn = 400020;const int maxm = 1<<12;const int inf = 0x3f3f3f3f;typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>order_set;//headtypedef long double LD;const LD eps = 1e-10;int dcmp(LD x) {    if(fabs(x) < eps) return 0;    return x < 0 ? -1 : 1;}LD sqr(LD x) { return x * x; }struct Point{    LD x, y;    Point(LD x = 0, LD y = 0):x(x), y(y) {}    void read() { cin >> x >> y; }};Point operator - (const Point& A, const Point& B) {    return Point(A.x - B.x, A.y - B.y);}bool operator == (const Point& A, const Point& B) {    return dcmp(A.x - B.x) == 0 && dcmp(A.y - B.x) == 0;}LD Dot(const Point& A, const Point& B) {    return A.x * B.x + A.y * B.y;}LD Length(const Point& A) { return sqrt(Dot(A, A)); }LD angle(const Point& A) { return atan2(A.y, A.x); }struct Circle{    Point c;    LD r;    Circle() {}    Circle(Point c, LD r):c(c), r(r) {}    Point point(LD a) {        return Point(c.x + cos(a) * r, c.y + sin(a) * r);    }};LD t1, t2, T1, T2;Point p[3];Circle o[3];vector<Point> sol;bool OnCircle(Point p, Circle C) {    return dcmp(Length(p - C.c) - C.r) == 0;}bool getCirclesolsection(Circle C1, Circle C2) {    LD &r1 = C1.r, &r2 = C2.r;    LD &x1 = C1.c.x, &x2 = C2.c.x, &y1 = C1.c.y, &y2 = C2.c.y;    LD d = Length(C1.c - C2.c);    if(dcmp(fabs(r1-r2) - d) > 0) return true;    if(dcmp(r1 + r2 - d) < 0) return false;    LD d2 = Dot(C1.c - C2.c, C1.c - C2.c);    LD a = r1*(x1-x2)*2, b = r1*(y1-y2)*2, c = r2*r2-r1*r1-d*d;    LD p = a*a+b*b, q = -a*c*2, r = c*c-b*b;    LD cosa, sina, cosb, sinb;    //One solsection    if(dcmp(d - (r1 + r2)) == 0 || dcmp(d - fabs(r1 - r2)) == 0) {        cosa = -q / p / 2;        sina = sqrt(1 - sqr(cosa));        Point p(x1 + C1.r * cosa, y1 + C1.r * sina);        if(!OnCircle(p, C2)) p.y = y1 - C1.r * sina;        sol.push_back(p);        return true;    }    //Two solsections    LD delta = sqrt(q * q - p * r * 4);    cosa = (delta - q) / p / 2;    cosb = (-delta - q) / p / 2;    sina = sqrt(1 - sqr(cosa));    sinb = sqrt(1 - sqr(cosb));    Point p1(x1 + C1.r * cosa, y1 + C1.r * sina);    Point p2(x1 + C1.r * cosb, y1 + C1.r * sinb);    if(!OnCircle(p1, C2)) p1.y = y1 - C1.r * sina;    if(!OnCircle(p2, C2)) p2.y = y1 - C1.r * sinb;    if(p1 == p2)  p1.y = y1 - C1.r * sina;    sol.push_back(p1);    sol.push_back(p2);    return true;}bool Include(Circle C1, Circle C2) {    LD d = Length(C1.c - C2.c);    if(dcmp(fabs(C1.r-C2.r) - d) > 0) return true;    return false;}bool InAllCircle(const Point& t) {    for(int i = 0; i < 3; i++) {        LD d = Length(t - o[i].c);        if(dcmp(d - o[i].r) > 0) return false;    }    return true;}//判断3个圆是否有交bool check() {    sol.clear();    for(int i = 0; i < 3; i++)        for(int j = i + 1; j < 3; j++)            if(!getCirclesolsection(o[i], o[j])) return false;    for(int i = 0; i < 3; i++)        for(int j = i + 1; j < 3; j++)            if(Include(o[i], o[j])) return true;    for(Point t : sol)        if(InAllCircle(t)) return true;    return false;}int main(){    cin>>t1>>t2;    for(int i = 0; i < 3; i++) p[i].read();    LD AB = Length(p[1] - p[0]);    LD AC = Length(p[2] - p[0]);    LD BC = Length(p[2] - p[1]);    T1 = AC + BC + t1;    T2 = AB + t2;    if(dcmp(T2 - AC - BC) >= 0){        LD ans = min(T1, T2);        printf("%.10Lf\n", ans);        return 0;    }    LD l = 0, r = min(T1 - BC, T2);    for(int i = 0; i < 100; i++){        LD mid = (l + r) / 2.0;        o[0] = Circle(p[0], mid);        o[1] = Circle(p[1], T2 - mid);        o[2] = Circle(p[2], T1 - BC - mid);        if(check()) l = mid;        else r = mid;    }    printf("%.10Lf\n", l);    return 0;}


0 0
原创粉丝点击