The Farthest Point
Source: aizu

The Farthest Point

Anant is on one of the vertices, say the starting vertex, of a rectangular cuboid (a hexahedron with all of its faces being rectangular). The surface of the cuboid constitutes the entire world of the ant.

We’d like to know which point on the surface of the cuboid is the farthest for the ant from the starting vertex. You may think that the opposite vertex, that is, the opposite end of the interior diagonal from the starting vertex, is the farthest. The opposite vertex is, however, not necessarily the farthest.

For example, on the surface of a cuboid of size $1 \times 1 \times 2$, the distance from a vertex to the opposite vertex is the square root of 8. The distance to the farthest point is, however, the square root of 65/8 (Figure F.1).


Figure F.1. Rectangular cuboid of size 1 × 1 × 2, and its net


You are given the size of the rectangular cuboid. Write a program which calculates the distance from the starting vertex to the farthest point.

Input

The input consists of a single test case of the following format.

$a$ $b$ $c$


The three integers $a$, $b$, and $c$ mean that the size of the rectangular cuboid is $a \times b \times c$. All of them are between 1 and 100, inclusive.

Output

Output a line containing the distance from the starting vertex to the farthest point. The relative error of the output must be less than or equal to $10^{−9}$.

Sample Input 1
1 1 2

Sample Output 1
2.850438562747845

Sample Input 2
10 10 10

Sample Output 2
22.360679774997898

Sample Input 3
100 2 3

Sample Output 3
101.0503923792481

Sample Input 4
2 3 5

Sample Output 4
7.093659140387279

Sample Input 5
84 41 51

Sample Output 5
124.582755157578


C++ solution:
#include <bits/stdc++.h>
using namespace std;



//------------------------------//
// 幾何の基本要素 (点, 線分, 円)
//------------------------------//

// basic settings
long double EPS = 1e-10;  // to be set appropriately
constexpr long double PI = 3.141592653589793238462643383279502884L;
long double torad(long double deg) {return (long double)(deg) * PI / 180;}
long double todeg(long double ang) {return ang * 180 / PI;}

// Point or Vector
template<class DD> struct Point {
    // inner value
    DD x, y;
    
    // constructor
    constexpr Point() : x(0), y(0) {}
    constexpr Point(DD x, DD y) : x(x), y(y) {}
    
    // various functions
    constexpr Point conj() const {return Point(x, -y);}
    constexpr DD dot(const Point &r) const {return x * r.x + y * r.y;}
    constexpr DD cross(const Point &r) const {return x * r.y - y * r.x;}
    constexpr DD norm() const {return dot(*this);}
    constexpr long double abs() const {return sqrt(norm());}
    constexpr long double arg() const {
        if (this->eq(Point(0, 0))) return 0L;
        else if (x < -EPS && this->eq(Point(x, 0))) return PI;
        else return atan2((long double)(y), (long double)(x));
    }
    constexpr bool eq(const Point &r) const {return (*this - r).abs() <= EPS;}
    constexpr Point rot90() const {return Point(-y, x);}
    constexpr Point rot(long double ang) const {
        return Point(cos(ang) * x - sin(ang) * y, sin(ang) * x + cos(ang) * y);
    }
    
    // arithmetic operators
    constexpr Point operator - () const {return Point(-x, -y);}
    constexpr Point operator + (const Point &r) const {return Point(*this) += r;}
    constexpr Point operator - (const Point &r) const {return Point(*this) -= r;}
    constexpr Point operator * (const Point &r) const {return Point(*this) *= r;}
    constexpr Point operator / (const Point &r) const {return Point(*this) /= r;}
    constexpr Point operator * (DD r) const {return Point(*this) *= r;}
    constexpr Point operator / (DD r) const {return Point(*this) /= r;}
    constexpr Point& operator += (const Point &r) {
        x += r.x, y += r.y;
        return *this;
    }
    constexpr Point& operator -= (const Point &r) {
        x -= r.x, y -= r.y;
        return *this;
    }
    constexpr Point& operator *= (const Point &r) {
        DD tx = x, ty = y;
        x = tx * r.x - ty * r.y;
        y = tx * r.y + ty * r.x;
        return *this;
    }
    constexpr Point& operator /= (const Point &r) {
        return *this *= r.conj() / r.norm();
    }
    constexpr Point& operator *= (DD r) {
        x *= r, y *= r;
        return *this;
    }
    constexpr Point& operator /= (DD r) {
        x /= r, y /= r;
        return *this;
    }

    // friend functions
    friend ostream& operator << (ostream &s, const Point &p) {
        return s << '(' << p.x << ", " << p.y << ')';
    }
    friend constexpr Point conj(const Point &p) {return p.conj();}
    friend constexpr DD dot(const Point &p, const Point &q) {return p.dot(q);}
    friend constexpr DD cross(const Point &p, const Point &q) {return p.cross(q);}
    friend constexpr DD norm(const Point &p) {return p.norm();}
    friend constexpr long double abs(const Point &p) {return p.abs();}
    friend constexpr long double arg(const Point &p) {return p.arg();}
    friend constexpr bool eq(const Point &p, const Point &q) {return p.eq(q);}
    friend constexpr Point rot90(const Point &p) {return p.rot90();}
    friend constexpr Point rot(const Point &p, long long ang) {return p.rot(ang);}
};

// necessary for some functions
template<class DD> constexpr bool operator < (const Point<DD> &p, const Point<DD> &q) {
    return (abs(p.x - q.x) > EPS ? p.x < q.x : p.y < q.y);
}

// Line
template<class DD> struct Line : vector<Point<DD>> {
    Line(Point<DD> a = Point<DD>(0, 0), Point<DD> b = Point<DD>(0, 0)) {
        this->push_back(a);
        this->push_back(b);
    }
    friend ostream& operator << (ostream &s, const Line<DD> &l) {
        return s << '{' << l[0] << ", " << l[1] << '}';
    }
};

// Circle
template<class DD> struct Circle : Point<DD> {
    DD r;
    Circle(Point<DD> p = Point<DD>(0, 0), DD r = 0) : Point<DD>(p), r(r) {}
    friend ostream& operator << (ostream &s, const Circle<DD> &c) {
        return s << '(' << c.x << ", " << c.y << ", " << c.r << ')';
    }
};


//------------------------------//
// 点や線分の位置関係
//------------------------------//

// arg sort
// by defining comparison
template<class DD> void arg_sort(vector<Point<DD>> &v) {
    auto sign = [&](const Point<DD> &p) -> int {
        if (abs(p.x) <= EPS && abs(p.y) <= EPS) return 0;
        else if (p.y < -EPS || (abs(p.y) <= EPS && p.x > EPS)) return -1;
        else return 1;
    };
    auto cmp = [&](const Point<DD> &p, const Point<DD> &q) -> bool {
        if (sign(p) != sign(q)) return sign(p) < sign(q);
        return (abs(cross(p, q)) > EPS ? cross(p, q) > EPS : norm(p) < norm(q));
    };
    sort(v.begin(), v.end(), cmp);
}
// by calculating arg directly
template<class DD> void arg_sort_direct(vector<Point<DD>> &v) {
    auto cmp = [&](const Point<DD> &p, const Point<DD> &q) -> bool {
        return (abs(arg(p) - arg(q)) > EPS ? arg(p) < arg(q) : norm(p) < norm(q));
    };
    sort(v.begin(), v.end(), cmp);
}

// 粗
// 1：a-bから見てcは左側(反時計回り)、-1：a-bから見てcは右側(時計回り)、0：一直線上
template<class DD> int simple_ccw
 (const Point<DD> &a, const Point<DD> &b, const Point<DD> &c) {
    if (cross(b-a, c-a) > EPS) return 1;
    if (cross(b-a, c-a) < -EPS) return -1;
    return 0;
}

// 精
// 1：a-bから見てcは左側(反時計回り)、-1：a-bから見てcは右側(時計回り)
// 2：c-a-bの順に一直線上、-2：a-b-cの順に一直線上、0：a-c-bの順に一直線上
template<class DD> int ccw
 (const Point<DD> &a, const Point<DD> &b, const Point<DD> &c) {
    if (cross(b-a, c-a) > EPS) return 1;
    if (cross(b-a, c-a) < -EPS) return -1;
    if (dot(b-a, c-a) < -EPS) return 2;
    if (norm(b-a) < norm(c-a) - EPS) return -2;
    return 0;
}

// 点と三角形の包含関係(辺上については判定していない)
template<class DD> bool is_contain
 (const Point<DD> &p, const Point<DD> &a, const Point<DD> &b, const Point<DD> &c) {
    int r1 = simple_ccw(p, b, c), r2 = simple_ccw(p, c, a), r3 = simple_ccw(p, a, b);
    if (r1 == 1 && r2 == 1 && r3 == 1) return true;
    if (r1 == -1 && r2 == -1 && r3 == -1) return true;
    return false;
}


//------------------------------//
// 線分の交差判定や距離計算
//------------------------------//

template<class DD> int ccw_for_dis
 (const Point<DD> &a, const Point<DD> &b, const Point<DD> &c) {
    if (cross(b-a, c-a) > EPS) return 1;
    if (cross(b-a, c-a) < -EPS) return -1;
    if (dot(b-a, c-a) < -EPS) return 2;
    if (norm(b-a) < norm(c-a) - EPS) return -2;
    return 0;
}
template<class DD> Point<DD> proj(const Point<DD> &p, const Line<DD> &l) {
    DD t = dot(p - l[0], l[1] - l[0]) / norm(l[1] - l[0]);
    return l[0] + (l[1] - l[0]) * t;
}
template<class DD> Point<DD> refl(const Point<DD> &p, const Line<DD> &l) {
    return p + (proj(p, l) - p) * 2;
}
template<class DD> bool is_inter_PL(const Point<DD> &p, const Line<DD> &l) {
    return (abs(p - proj(p, l)) < EPS);
}
template<class DD> bool is_inter_PS(const Point<DD> &p, const Line<DD> &s) {
    return (ccw_for_dis(s[0], s[1], p) == 0);
}
template<class DD> bool is_inter_LL(const Line<DD> &l, const Line<DD> &m) {
    return (abs(cross(l[1] - l[0], m[1] - m[0])) > EPS ||
            abs(cross(l[1] - l[0], m[0] - l[0])) < EPS);
}
template<class DD> bool is_inter_SS(const Line<DD> &s, const Line<DD> &t) {
    if (eq(s[0], s[1])) return is_inter_PS(s[0], t);
    if (eq(t[0], t[1])) return is_inter_PS(t[0], s);
    return (ccw_for_dis(s[0], s[1], t[0]) * ccw_for_dis(s[0], s[1], t[1]) <= 0 &&
            ccw_for_dis(t[0], t[1], s[0]) * ccw_for_dis(t[0], t[1], s[1]) <= 0);
}
template<class DD> DD distance_PL(const Point<DD> &p, const Line<DD> &l) {
    return abs(p - proj(p, l));
}
template<class DD> DD distance_PS(const Point<DD> &p, const Line<DD> &s) {
    Point h = proj(p, s);
    if (is_inter_PS(h, s)) return abs(p - h);
    return min(abs(p - s[0]), abs(p - s[1]));
}
template<class DD> DD distance_LL(const Line<DD> &l, const Line<DD> &m) {
    if (is_inter_LL(l, m)) return 0;
    else return distance_PL(m[0], l);
}
template<class DD> DD distance_SS(const Line<DD> &s, const Line<DD> &t) {
    if (is_inter_SS(s, t)) return 0;
    else return min(min(distance_PS(s[0], t), distance_PS(s[1], t)),
                    min(distance_PS(t[0], s), distance_PS(t[1], s)));
}


//------------------------------//
// 円や直線の交点
//------------------------------//

template<class DD> Point<DD> proj_for_crosspoint(const Point<DD> &p, const Line<DD> &l) {
    DD t = dot(p - l[0], l[1] - l[0]) / norm(l[1] - l[0]);
    return l[0] + (l[1] - l[0]) * t;
}
template<class DD> vector<Point<DD>> crosspoint(const Line<DD> &l, const Line<DD> &m) {
    vector<Point<DD>> res;
    DD d = cross(m[1] - m[0], l[1] - l[0]);
    if (abs(d) < EPS) return vector<Point<DD>>();
    res.push_back(l[0] + (l[1] - l[0]) * cross(m[1] - m[0], m[1] - l[0]) / d);
    return res;
}
template<class DD> vector<Point<DD>> crosspoint_SS(const Line<DD> &l, const Line<DD> &m) {
    if (is_inter_SS(l, m)) return crosspoint(l, m);
    else return vector<Point<DD>>();
}
template<class DD> vector<Point<DD>> crosspoint(const Circle<DD> &e, const Circle<DD> &f) {
    vector<Point<DD>> res;
    DD d = abs(e - f);
    if (d < EPS) return vector<Point<DD>>();
    if (d > e.r + f.r + EPS) return vector<Point<DD>>();
    if (d < abs(e.r - f.r) - EPS) return vector<Point<DD>>();
    DD rcos = (d * d + e.r * e.r - f.r * f.r) / (2.0 * d), rsin;
    if (e.r - abs(rcos) < EPS) rsin = 0;
    else rsin = sqrt(e.r * e.r - rcos * rcos);
    Point<DD> dir = (f - e) / d;
    Point<DD> p1 = e + dir * Point(rcos, rsin);
    Point<DD> p2 = e + dir * Point(rcos, -rsin);
    res.push_back(p1);
    if (!eq(p1, p2)) res.push_back(p2);
    return res;
}
template<class DD> vector<Point<DD>> crosspoint(const Circle<DD> &e, const Line<DD> &l) {
    vector<Point<DD>> res;
    Point<DD> p = proj_for_crosspoint(e, l);
    DD rcos = abs(e - p), rsin;
    if (rcos > e.r + EPS) return vector<Point<DD>>();
    else if (e.r - rcos < EPS) rsin = 0;
    else rsin = sqrt(e.r * e.r - rcos * rcos);
    Point<DD> dir = (l[1] - l[0]) / abs(l[1] - l[0]);
    Point<DD> p1 = p + dir * rsin;
    Point<DD> p2 = p - dir * rsin;
    res.push_back(p1);
    if (!eq(p1, p2)) res.push_back(p2);
    return res;
}


//------------------------------//
// 接線
//------------------------------//

// tanline
template<class DD> vector<Point<DD>> tanline(const Point<DD> &p, const Circle<DD> &c) {
    vector<Point<DD>> res;
    DD d = norm(p - c);
    DD l = d - c.r * c.r;
    if (l < -EPS) return res;
    if (l <= 0.0) l = 0.0;
    Point<DD> cq = (p - c) * (c.r * c.r / d);
    Point<DD> qs = rot90((p - c) * (c.r * sqrt(l) / d));
    Point<DD> s1 = c + cq + qs, s2 = c + cq - qs;
    res.push_back(s1);
    res.push_back(s2);
    return res;
}

// common tanline, a and b must be different!
// Line[0] is tangent point in a
template<class DD> vector<Line<DD>> com_tanline(const Circle<DD> &a, const Circle<DD> &b) {
    vector<Line<DD>> res;
    // intersect
    if (abs(a - b) > abs(a.r - b.r) + EPS) {
        if (abs(a.r - b.r) < EPS) {
            Point<DD> dir = b - a;
            dir = rot90(dir * (a.r / abs(dir)));
            res.push_back(Line(a + dir, b + dir));
            res.push_back(Line(a - dir, b - dir));
        }
        else {
            Point<DD> p = a * -b.r + b * a.r;
            p = p * (1.0 / (a.r - b.r));
            vector<Point<DD>> bs = tanline(p, a);
            vector<Point<DD>> as = tanline(p, b);
            for (int i = 0; i < min(as.size(), bs.size()); ++i) {
                res.push_back(Line(bs[i], as[i]));
            }
        }
    }
    // inscribed
    else if (abs(abs(a - b) - abs(a.r - b.r)) <= EPS) {
        Point<DD> dir = b - a;
        if (a.r > b.r) dir = dir * (a.r / abs(dir));
        else dir = dir * (-a.r / abs(dir));
        Point<DD> p = a + dir;
        res.push_back(Line(p, p + rot90(dir)));
    }
    // disjoint
    if (abs(a - b) > a.r + b.r + EPS) {
        Point<DD> p = a * b.r + b * a.r;
        p = p * (1.0 / (a.r + b.r));
        vector<Point<DD>> bs = tanline(p, a);
        vector<Point<DD>> as = tanline(p, b);
        for (int i = 0; i < min(as.size(), bs.size()); ++i) {
            res.push_back(Line(bs[i], as[i]));
        }
    }
    // circumscribed
    else if (abs(abs(a - b) - (a.r + b.r)) <= EPS) {
        Point<DD> dir = b - a;
        dir = dir * (a.r / abs(dir));
        Point<DD> p = a + dir;
        res.push_back(Line(p, p + rot90(dir)));
    }
    return res;
}


//------------------------------//
// 多角形アルゴリズム
//------------------------------//

// 多角形の符号付面積
template<class DD> DD calc_area(const vector<Point<DD>> &pol) {
    DD res = 0.0;
    for (int i = 0; i < pol.size(); ++i) {
        res += cross(pol[i], pol[(i+1)%pol.size()]);
    }
    return res/2.0L;
}

// 点と多角形の包含関係
// 2: in, 1: on, 0: out
template<class DD> int is_contain(const vector<Point<DD>> &pol, const Point<DD> &p) {
    int n = (int)pol.size();
    int isin = 0;
    for (int i = 0; i < n; ++i) {
        Point<DD> a = pol[i] - p, b = pol[(i+1)%n] - p;
        if (a.y > b.y) swap(a, b);
        if (a.y <= 0 && b.y > 0) if (cross(a, b) < 0) isin = 1-isin;
        if (cross(a, b) == 0 && dot(a, b) <= 0) return 1;
    }
    if (isin) return 2;
    else return 0;
}


// 凸性判定
template<class DD> int ccw_for_isconvex
 (const Point<DD> &a, const Point<DD> &b, const Point<DD> &c) {
    if (cross(b-a, c-a) > EPS) return 1;
    if (cross(b-a, c-a) < -EPS) return -1;
    return 0;
}
template<class DD> bool is_convex(const vector<Point<DD>> &ps) {
    int n = (int)ps.size();
    for (int i = 0; i < n; ++i) {
        if (ccw_for_isconvex(ps[i], ps[(i+1)%n], ps[(i+2)%n]) == -1) return false;
    }
    return true;
}

// 凸包 (一直線上の3点を含めない)
template<class DD> vector<Point<DD>> convex_hull(vector<Point<DD>> &ps) {
    int n = (int)ps.size();
    if (n == 1) return ps;
    vector<Point<DD>> res(2*n);
    auto cmp = [&](const Point<DD> &p, const Point<DD> &q) -> bool {
        return (abs(p.x - q.x) > EPS ? p.x < q.x : p.y < q.y);
    };
    sort(ps.begin(), ps.end(), cmp);
    int k = 0;
    for (int i = 0; i < n; ++i) {
        if (k >= 2) {
            while (cross(res[k-1] - res[k-2], ps[i] - res[k-2]) < EPS) {
                --k;
                if (k < 2) break;
            }
        }
        res[k] = ps[i]; ++k;
    }
    int t = k+1;
    for (int i = n-2; i >= 0; --i) {
        if (k >= t) {
            while (cross(res[k-1] - res[k-2], ps[i] - res[k-2]) < EPS) {
                --k;
                if (k < t) break;
            }
        }
        res[k] = ps[i]; ++k;
    }
    res.resize(k-1);
    return res;
}

// 凸包 (一直線上の3点を含める)
template<class DD> vector<Point<DD>> convex_hull_colinear(vector<Point<DD>> &ps) {
    int n = (int)ps.size();
    if (n == 1) return ps;
    vector<Point<DD>> res(2*n);
    auto cmp = [&](const Point<DD> &p, const Point<DD> &q) -> bool {
        return (abs(p.x - q.x) > EPS ? p.x < q.x : p.y < q.y);
    };
    sort(ps.begin(), ps.end(), cmp);
    int k = 0;
    for (int i = 0; i < n; ++i) {
        if (k >= 2) {
            while (cross(res[k-1] - res[k-2], ps[i] - res[k-2]) < -EPS) {
                --k;
                if (k < 2) break;
            }
        }
        res[k] = ps[i]; ++k;
    }
    int t = k+1;
    for (int i = n-2; i >= 0; --i) {
        if (k >= t) {
            while (cross(res[k-1] - res[k-2], ps[i] - res[k-2]) < -EPS) {
                --k;
                if (k < t) break;
            }
        }
        res[k] = ps[i]; ++k;
    }
    res.resize(k-1);
    return res;
}

// Convex Cut
template<class DD> int ccw_for_convexcut
 (const Point<DD> &a, const Point<DD> &b, const Point<DD> &c) {
    if (cross(b-a, c-a) > EPS) return 1;
    if (cross(b-a, c-a) < -EPS) return -1;
    if (dot(b-a, c-a) < -EPS) return 2;
    if (norm(b-a) < norm(c-a) - EPS) return -2;
    return 0;
}
template<class DD> vector<Point<DD>> crosspoint_for_convexcut
 (const Line<DD> &l, const Line<DD> &m) {
    vector<Point<DD>> res;
    DD d = cross(m[1] - m[0], l[1] - l[0]);
    if (abs(d) < EPS) return vector<Point<DD>>();
    res.push_back(l[0] + (l[1] - l[0]) * cross(m[1] - m[0], m[1] - l[0]) / d);
    return res;
}
template<class DD> vector<Point<DD>> convex_cut
 (const vector<Point<DD>> &pol, const Line<DD> &l) {
    vector<Point<DD>> res;
    for (int i = 0; i < pol.size(); ++i) {
        Point<DD> p = pol[i], q = pol[(i+1)%pol.size()];
        if (ccw_for_convexcut(l[0], l[1], p) != -1) {
            if (res.size() == 0) res.push_back(p);
            else if (!eq(p, res[res.size()-1])) res.push_back(p);
        }
        if (ccw_for_convexcut(l[0], l[1], p) * ccw_for_convexcut(l[0], l[1], q) < 0) {
            vector<Point<DD>> temp = crosspoint_for_convexcut(Line(p, q), l);
            if (temp.size() == 0) continue;
            else if (res.size() == 0) res.push_back(temp[0]);
            else if (!eq(temp[0], res[res.size()-1])) res.push_back(temp[0]);
        }
    }
    return res;
}

// Voronoi Diagram
// pol: outer polygon, ps: points
// find the polygon nearest to ps[ind]
template<class DD> Line<DD> bisector(const Point<DD> &p, const Point<DD> &q) {
    Point<DD> c = (p + q) / 2.0L;
    Point<DD> v = (q - p) * Point(0.0L, 1.0L);
    v = v / abs(v);
    return Line(c - v, c + v);
}

template<class DD> vector<Point<DD>> voronoi
 (const vector<Point<DD>> &pol, const vector<Point<DD>> &ps, int ind) {
    vector<Point<DD>> res = pol;
    for (int i = 0; i < ps.size(); ++i) {
        if (i == ind) continue;
        Line<DD> l = bisector(ps[ind], ps[i]);
        res = convex_cut(res, l);
    }
    return res;
}


//------------------------------//
// 面積アルゴリズム
//------------------------------//

// 円と円の共通部分の面積
template<class DD> DD calc_common_area(const Circle<DD> &p, const Circle<DD> &q) {
    DD d = abs(p - q);
    if (d >= p.r + q.r - EPS) return 0;
    else if (d <= abs(p.r - q.r) + EPS) return min(p.r, q.r) * min(p.r, q.r) * PI;
    DD pcos = (p.r*p.r + d*d - q.r*q.r) / (p.r*d*2);
    DD pang = acosl(pcos);
    DD parea = p.r*p.r*pang - p.r*p.r*sin(pang*2)/2;
    DD qcos = (q.r*q.r + d*d - p.r*p.r) / (q.r*d*2);
    DD qang = acosl(qcos);
    DD qarea = q.r*q.r*qang - q.r*q.r*sin(qang*2)/2;
    return parea + qarea;
}

// 交点
template<class DD> int ccw_for_crosspoint_CS
 (const Point<DD> &a, const Point<DD> &b, const Point<DD> &c) {
    if (cross(b-a, c-a) > EPS) return 1;
    if (cross(b-a, c-a) < -EPS) return -1;
    if (dot(b-a, c-a) < -EPS) return 2;
    if (norm(b-a) < norm(c-a) - EPS) return -2;
    return 0;
}
template<class DD> bool isinterPS_crosspoint_CS(const Point<DD> &p, const Line<DD> &s) {
    return (ccw_for_crosspoint_CS(s[0], s[1], p) == 0);
}
template<class DD> Point<DD> proj_for_crosspoint_CS(const Point<DD> &p, const Line<DD> &l) {
    DD t = dot(p - l[0], l[1] - l[0]) / norm(l[1] - l[0]);
    return l[0] + (l[1] - l[0]) * t;
}
template<class DD> vector<Point<DD>> crosspoint_CS(const Circle<DD> &e, const Line<DD> &s) {
    vector<Point<DD>> res;
    Point<DD> p = proj_for_crosspoint_CS(e, s);
    DD rcos = abs(e - p), rsin;
    if (rcos > e.r + EPS) return vector<Point<DD>>();
    else if (e.r - rcos < EPS) rsin = 0;
    else rsin = sqrt(e.r * e.r - rcos * rcos);
    Point<DD> dir = (s[1] - s[0]) / abs(s[1] - s[0]);
    Point<DD> p1 = p - dir * rsin;
    Point<DD> p2 = p + dir * rsin;
    if (isinterPS_crosspoint_CS(p1, s)) res.push_back(p1);
    if (isinterPS_crosspoint_CS(p2, s) && !eq(p1, p2)) res.push_back(p2);
    return res;
}

// 原点, 点 x, 点 y とで囲まれる領域の面積 (三角形 ver と扇型 ver)
template<class DD> DD calc_element
 (const Point<DD> &x, const Point<DD> &y, DD r, bool triangle = true) {
    if (triangle) return cross(x, y) / 2;
    else {
        Point<DD> tmp = y * Point(x.x, -x.y);
        DD ang = atan2(tmp.y, tmp.x);
        return r * r * ang / 2;
    }
}

// 円 C と、三角形 ((0, 0), ia, ib) との共通部分の面積
template<class DD> DD calc_common_area
 (const Circle<DD> &c, const Point<DD> &ia, const Point<DD> &ib) {
    Point<DD> a = ia - c, b = ib - c;
    if (abs(a - b) < EPS) return 0;
    bool isin_a = (abs(a) < c.r + EPS);
    bool isin_b = (abs(b) < c.r + EPS);
    if (isin_a && isin_b) return calc_element(a, b, c.r, true);
    Circle<DD> oc(Point<DD>(0, 0), c.r);
    Line<DD> seg(a, b);
    auto cr = crosspoint_CS(oc, seg);
    if (cr.empty()) return calc_element(a, b, c.r, false);
    auto s = cr[0], t = cr.back();
    return calc_element(s, t, c.r, true)
        + calc_element(a, s, c.r, isin_a) + calc_element(t, b, c.r, isin_b);
}

// 円 c と多角形 pol の共通部分の面積
template<class DD> DD calc_common_area(const Circle<DD> &c, const vector<Point<DD>> &pol) {
    DD res = 0;
    int n = (int)pol.size();
    for (int i = 0; i < n; ++i) {
        res += calc_common_area(c, pol[i], pol[(i+1)%n]);
    }
    return res;
}


//------------------------------//
// その他
//------------------------------//

// 垂直二等分線
template<class DD> Line<DD> Bisector(const Point<DD> &p, const Point<DD> &q) {
    Point<DD> m = (p + q) / 2;
    Point<DD> x = m + rot90(q - p);
    return Line(m, x);
}

// 3 点を通る円
template<class DD> Circle<DD> CircumscribedCircle
(const Point<DD> &p, const Point<DD> &q, const Point<DD> &r) {
    if (simple_ccw(p, q, r) == 0) return Circle<DD>();
    Line<DD> pq = Bisector(p, q);
    Line<DD> pr = Bisector(p, r);
    vector<Point<DD>> centers = crosspoint(pq, pr);
    if (centers.empty()) return Circle<DD>();
    Point<DD> center = centers[0];
    DD radius = abs(center - p);
    return Circle(center, radius);
}


// AOJ 1460 - The Farthest Point
void AOJ_1460() {
    cout << fixed << setprecision(10);
    using DD = long double;
    vector<DD> a(3);
    cin >> a[0] >> a[1] >> a[2];
    sort(a.begin(), a.end());
    DD A = a[0], B = a[1], C = a[2];

    if (B > C * (C * 2 - A) / (C * 2 + A)) {
        cout << sqrt(A * A + B * B + C * C + A * B * 2) << endl;
    } else {
        Point<DD> p(0, 0);
        Point<DD> q(A, A + C * 2);
        Point<DD> r(A + B + C, A + B + C);
        Circle<DD> circle = CircumscribedCircle(p, q, r);
        cout << circle.r << endl;
    }
}


int main() {
    AOJ_1460();
}

Go solution:
package main

import (
	"fmt"
	"math"
	"sort"
)

func main() {
	var a, b, c float64
	fmt.Scan(&a, &b, &c)

	// Sort the dimensions in ascending order
	dimensions := []float64{a, b, c}
	sort.Float64s(dimensions)
	A := dimensions[0]
	B := dimensions[1]
	C := dimensions[2]

	var farthest float64

	// Check the condition to determine which formula to use
	if B > C*(2*C-A)/(2*C+A) {
		farthest = math.Sqrt(A*A + B*B + C*C + 2*A*B)
	} else {
		// The farthest point is the circumradius of the triangle formed by (0,0), (A, A+2C), (A+B+C, A+B+C)
		// The three points are:
		x1, y1 := 0.0, 0.0
		x2, y2 := A, A+2*C
		x3, y3 := A+B+C, A+B+C

		// Calculate the side lengths of the triangle
		aSide := math.Sqrt((x2-x3)*(x2-x3) + (y2-y3)*(y2-y3))
		bSide := math.Sqrt((x1-x3)*(x1-x3) + (y1-y3)*(y1-y3))
		cSide := math.Sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2))

		// Calculate the area of the triangle using Heron's formula
		s := (aSide + bSide + cSide) / 2
		area := math.Sqrt(s * (s - aSide) * (s - bSide) * (s - cSide))

		// Circumradius formula: (a*b*c)/(4*area)
		if area == 0 {
			// Collinear points, but according to problem statement, this shouldn't happen
			farthest = math.Max(math.Sqrt(x3*x3+y3*y3), math.Sqrt(x2*x2+y2*y2))
		} else {
			circumradius := (aSide * bSide * cSide) / (4 * area)
			farthest = circumradius
		}
	}

	fmt.Printf("%.15f\n", farthest)
}

Java solution:
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        double a = scanner.nextDouble();
        double b = scanner.nextDouble();
        double c = scanner.nextDouble();
        
        // Sort the dimensions to ensure a <= b <= c
        if (a > b) { double temp = a; a = b; b = temp; }
        if (b > c) { double temp = b; b = c; c = temp; }
        if (a > b) { double temp = a; a = b; b = temp; }
        
        double farthestDistance;
        if (b <= c * (2 * c - a) / (2 * c + a)) {
            // Calculate the radius of the circumscribed circle of points (0,0), (a, a+2c), (a+b+c, a+b+c)
            double x1 = 0, y1 = 0;
            double x2 = a, y2 = a + 2 * c;
            double x3 = a + b + c, y3 = a + b + c;
            
            double A = x2 - x1;
            double B = y2 - y1;
            double C = x3 - x1;
            double D = y3 - y1;
            
            double E = A * (x1 + x2) + B * (y1 + y2);
            double F = C * (x1 + x3) + D * (y1 + y3);
            
            double G = 2 * (A * (y3 - y1) - B * (x3 - x1));
            
            double centerX = (D * E - B * F) / G;
            double centerY = (A * F - C * E) / G;
            
            farthestDistance = Math.sqrt(centerX * centerX + centerY * centerY);
        } else {
            farthestDistance = Math.sqrt(a * a + b * b + c * c + 2 * a * b);
        }
        
        System.out.printf("%.15f\n", farthestDistance);
    }
}

JavaScript solution:
const readline = require('readline');

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

rl.on('line', (input) => {
    const [a, b, c] = input.split(' ').map(Number).sort((x, y) => x - y);
    let result;
    
    if (b > c * (2 * c - a) / (2 * c + a)) {
        result = Math.sqrt(a * a + b * b + c * c + 2 * a * b);
    } else {
        // The points in the unfolded plane
        const p = { x: 0, y: 0 };
        const q = { x: a, y: a + 2 * c };
        const r = { x: a + b + c, y: a + b + c };
        
        // Calculate the circumradius of triangle pqr
        const A = Math.sqrt((q.x - r.x) ** 2 + (q.y - r.y) ** 2);
        const B = Math.sqrt((p.x - r.x) ** 2 + (p.y - r.y) ** 2);
        const C = Math.sqrt((p.x - q.x) ** 2 + (p.y - q.y) ** 2);
        
        const area = Math.abs((p.x * (q.y - r.y) + q.x * (r.y - p.y) + r.x * (p.y - q.y)) / 2);
        const circumradius = (A * B * C) / (4 * area);
        result = circumradius;
    }
    
    console.log(result.toFixed(15));
    rl.close();
});

Python solution:
import math

def solve():
    a, b, c = map(int, input().split())
    # Sort the dimensions to ensure a <= b <= c
    dimensions = sorted([a, b, c])
    A, B, C = dimensions
    
    if B > C * (2 * C - A) / (2 * C + A):
        max_distance = math.sqrt(A**2 + B**2 + C**2 + 2 * A * B)
    else:
        # The farthest point is the circumradius of the triangle formed by (0,0), (A, A+2C), (A+B+C, A+B+C)
        # Points in 2D plane
        p = (0.0, 0.0)
        q = (float(A), float(A + 2 * C))
        r = (float(A + B + C), float(A + B + C))
        
        # Compute the sides of the triangle
        a_side = math.sqrt((q[0] - r[0])**2 + (q[1] - r[1])**2)
        b_side = math.sqrt((p[0] - r[0])**2 + (p[1] - r[1])**2)
        c_side = math.sqrt((p[0] - q[0])**2 + (p[1] - q[1])**2)
        
        # Compute area using Heron's formula
        s = (a_side + b_side + c_side) / 2
        area = math.sqrt(s * (s - a_side) * (s - b_side) * (s - c_side))
        
        if area == 0:
            # Collinear points, circumradius is infinity, but problem says dimensions are >=1
            # So this case shouldn't happen per problem constraints
            max_distance = max(a_side, b_side, c_side) / 2
        else:
            circumradius = (a_side * b_side * c_side) / (4 * area)
            max_distance = circumradius
    
    print("{0:.15f}".format(max_distance))

solve()

Ruby solution:
def solve
  a, b, c = gets.split.map(&:to_f)
  dimensions = [a, b, c].sort
  a_small = dimensions[0]
  b_small = dimensions[1]
  c_large = dimensions[2]

  if b_small > c_large * (2 * c_large - a_small) / (2 * c_large + a_small)
    distance = Math.sqrt(a_small**2 + b_small**2 + c_large**2 + 2 * a_small * b_small)
  else
    # The farthest point is the circumradius of the triangle formed by (0,0), (a, a+2c), (a+b+c, a+b+c)
    # The three points form a right triangle, so the circumradius is half the hypotenuse
    # The hypotenuse is the distance between (0,0) and (a+b+c, a+b+c + 2c)
    # But in the sample input 1, the points are (0,0), (1,1+4), (1+1+2, 1+1+2) => (0,0), (1,5), (4,4)
    # The circumradius is computed as the distance from the center to any vertex
    # So we need to find the circumradius of the triangle with vertices (0,0), (A, A + 2C), (A+B+C, A+B+C)
    x1, y1 = 0.0, 0.0
    x2, y2 = a_small, a_small + 2 * c_large
    x3, y3 = a_small + b_small + c_large, a_small + b_small + c_large

    # Calculate the perpendicular bisectors of two sides and find their intersection
    # Midpoint of (x1,y1) and (x2,y2)
    mid1_x = (x1 + x2) / 2.0
    mid1_y = (y1 + y2) / 2.0
    # Slope of the line (x1,y1)-(x2,y2)
    dx1 = x2 - x1
    dy1 = y2 - y1
    # Slope of the perpendicular bisector
    # The equation is (y - mid1_y) = -dx1/dy1 (x - mid1_x)
    # Similarly for the second side (x1,y1)-(x3,y3)
    mid2_x = (x1 + x3) / 2.0
    mid2_y = (y1 + y3) / 2.0
    dx2 = x3 - x1
    dy2 = y3 - y1

    # The two lines are:
    # Line1: (x - mid1_x) * dx1 + (y - mid1_y) * dy1 = 0
    # Line2: (x - mid2_x) * dx2 + (y - mid2_y) * dy2 = 0
    # Solving the system of equations:
    # dx1*(x) + dy1*(y) = dx1*mid1_x + dy1*mid1_y
    # dx2*(x) + dy2*(y) = dx2*mid2_x + dy2*mid2_y
    # Using Cramer's rule
    determinant = dx1 * dy2 - dx2 * dy1
    if determinant.abs < 1e-10
      # Points are colinear, handle separately (though problem says dimensions are positive)
      # In this case, the farthest distance would be the maximum of the distances between the points
      distance = [Math.hypot(x2 - x1, y2 - y1), Math.hypot(x3 - x1, y3 - y1)].max
    else
      cx = ( (dy2 * (dx1 * mid1_x + dy1 * mid1_y)) - (dy1 * (dx2 * mid2_x + dy2 * mid2_y)) ) / determinant
      cy = ( (dx1 * (dx2 * mid2_x + dy2 * mid2_y)) - (dx2 * (dx1 * mid1_x + dy1 * mid1_y)) ) / determinant
      distance = Math.hypot(cx - x1, cy - y1)
    end
  end
  puts "%.15f" % distance
end

solve