#include using namespace std; typedef long double T; const T eps = 1e-12; struct Vec { T x, y; }; Vec operator+ (Vec a, Vec b) { return { a.x + b.x, a.y + b.y }; } Vec operator- (Vec a, Vec b) { return { a.x - b.x, a.y - b.y }; } Vec operator* (Vec a, T b) { return { a.x * b, a.y * b }; } Vec operator/ (Vec a, T b) { return { a.x / b, a.y / b }; } T dot(Vec a, Vec b) { return a.x * b.x + a.y * b.y; } T prod(Vec a, Vec b) { return a.x * b.y - a.y * b.x; } T len(Vec v) { return sqrt(dot(v, v)); } T len2(Vec v) { return dot(v, v); } Vec norm(Vec v) { return v / len(v); } struct ParamLine { Vec p, v; ParamLine() = default; ParamLine(Vec a, Vec b) { p = a; v = b - a; } }; Vec project(const ParamLine &l, const Vec &u) { return l.p + l.v * dot((u - l.p), l.v) / len2(l.v); } T dist(const ParamLine &l, const Vec &u) { return abs(prod(l.v, u - l.p) / len(l.v)); } inline bool zero(const T &t) { return abs(t) < eps; } T intersect(ParamLine a, ParamLine b) { auto d = prod(a.v, b.v); if(zero(d)) return -1; return prod(b.p - a.p, b.v) / d; } ParamLine sym(ParamLine a, ParamLine b) { a.p = (a.p + b.p) / 2; return a; } bool shadowed(const Vec &v, const ParamLine &l) { auto p = dot(l.v, v - l.p) / len2(l.v); return p > -eps && p < 1 + eps; } int n; vector poly; vector hor, ver; bool inside(Vec v) { bool in = false; for(auto h: hor) { //printf("%d %Lf %Lf\n", shadowed(v, h), v.y, h.p.y); if(shadowed(v, h) && v.y > h.p.y) in = !in; } return in; } T height(Vec p) { //printf("punkt %Lf %Lf\n", p.x, p.y); if(!inside(p)) return 0; T ans = 1e20; for(auto h: hor) if(shadowed(p, h)) ans = min(ans, abs(p.y - h.p.y)); for(auto v: ver) if(shadowed(p, v)) ans = min(ans, abs(p.x - v.p.x)); for(int i = 0; i < n; i++) ans = min(ans, max(abs(p.x - poly[i].x), abs(p.y - poly[i].y))); return ans; } int main() { scanf("%d", &n); Vec st, en; scanf("%Lf %Lf %Lf %Lf", &st.x, &st.y, &en.x, &en.y); for(int i = 0; i < n; i++) { Vec v; scanf("%Lf %Lf", &v.x, &v.y); while(poly.size() > 1 && zero(prod(v - poly.back(), poly[poly.size()-2] - poly.back()))) poly.pop_back(); poly.push_back(v); } while(zero(prod(poly[0] - poly.back(), poly[poly.size()-2] - poly.back()))) poly.pop_back(); while(zero(prod(poly[1] - poly[0], poly.back() - poly[0]))) poly.erase(poly.begin()); n = poly.size(); assert(n % 2 == 0); if(poly[0].x == poly[1].x) { swap(st.x, st.y); swap(en.x, en.y); for(auto &v: poly) swap(v.x, v.y); } poly.push_back(poly[0]); poly.push_back(poly[1]); for(int i = 0; i < n; i += 2) { hor.emplace_back(poly[i], poly[i+1]); ver.emplace_back(poly[i+1], poly[i+2]); } ParamLine l(st, en); vector div = hor; div.insert(div.end(), ver.begin(), ver.end()); for(int i = 0; i < hor.size(); i++) for(int j = 0; j < i; j++) div.push_back(sym(hor[i], hor[j])); for(int i = 0; i < ver.size(); i++) for(int j = 0; j < i; j++) div.push_back(sym(ver[i], ver[j])); for(int i = 0; i < n; i++) { auto p = poly[i+1], a = poly[i] - poly[i+1], b = poly[i+2] - poly[i+1]; div.push_back(ParamLine(p, p + (norm(a) + norm(b)) / 2)); } vector pts = { 0, 1 }; for(auto d: div) { auto t = intersect(l, d); if(t > 0 && t < 1) pts.push_back(t); } sort(pts.begin(), pts.end()); auto leng = len(l.v); T ans = 0, last = -1, lastH = 0; for(auto t: pts) { auto h = height(l.p + l.v * t); if(last >= 0) ans += len({leng * (t - last), h - lastH}); //printf("add %Lf\n", len({leng * (t - last), h - lastH})); last = t; lastH = h; //printf("%Lf\n", h); } printf("%.12Lf\n", ans); } /* punkt 0.000000 3.000000 0 3.000000 0.000000 0 3.000000 4.000000 0.000000 punkt 1.000000 3.000000 0 3.000000 0.000000 0 3.000000 4.000000 0.000000 punkt 1.000000 3.000000 0 3.000000 0.000000 0 3.000000 4.000000 0.000000 punkt 2.000000 3.000000 0 3.000000 0.000000 0 3.000000 4.000000 0.000000 punkt 3.000000 3.000000 0 3.000000 0.000000 0 3.000000 4.000000 0.000000 punkt 3.000000 3.000000 0 3.000000 0.000000 0 3.000000 4.000000 0.000000 punkt 4.000000 3.000000 0 3.000000 0.000000 0 3.000000 4.000000 0.000000 4.000000000000 */