#include using namespace std; #define LL long long #define LD long double #define PII pair #define VI vector #define VPII vector #define f first #define s second #define MP make_pair #define PB push_back #define endl '\n' #define SIZ(c) (int)(c).size() #define ALL(c) (c).begin(), (c).end() #define REP(i, n) for (int i = 0; i < (int)(n); i++) #define FOR(i, b, e) for (int i = (b); i <= (int)(e); i++) #define FORD(i, b, e) for (int i = (b); i >= (int)(e); i--) #define ll LL #define st f #define nd s #define mp MP #define pb PB #define eb emplace_back #define siz(c) SIZ(c) const int inf = 1e9 + 7; const LL INF = 1e18L + 7; #define sim template ostream & operator << (ostream &p, pair x) {return p << "<" << x.f << ", " << x.s << ">";} sim> auto operator << (ostream &p, n y) -> typename enable_if::value, decltype(y.begin(), p)>::type {int o = 0; p << "{"; for (auto c : y) {if (o++) p << ", "; p << c;} return p << "}";} void dor() {cerr << "\n";} sim, class...s> void dor(n p, s...y) {cerr << p << " "; dor(y...);} sim, class s> void mini(n &p, s y) {if (p > y) p = y;} sim, class s> void maxi(n &p, s y) {if (p < y) p = y;} #ifdef DEB #define debug(...) dor(__FUNCTION__, ":", __LINE__, ": ", __VA_ARGS__) #else #define debug(...) #endif #define I(x) #x " =", (x), " " #define punkt pair #define PLD pair const LD eps = 1e-13; struct prosta { LD A, B, C; prosta(LD a, LD b, LD c) { A = a; B = b; C = c; } }; punkt operator+ (punkt a, punkt b) { return MP(a.f + b.f, a.s + b.s); } punkt operator- (punkt a, punkt b) { return MP(a.f - b.f, a.s - b.s); } punkt operator* (punkt a, LD r) { return MP(a.f * r, a.s * r); } punkt operator* (LD r, punkt a) { return MP(a.f * r, a.s * r); } LD len(punkt a) { return sqrt(a.f * a.f + a.s * a.s); } LD dist(punkt a, punkt b) { return len(a - b); } LD dist2(punkt a) { return a.f * a.f + a.s * a.s; } LD dist2(punkt a, punkt b) { return dist2(a - b); } punkt rzut(prosta a, punkt b) { return b - (b.f * a.A + b.s * a.B - a.C) / (a.A * a.A + a.B * a.B) * make_pair(a.A, a.B); } prosta przezpunkty(punkt k, punkt l) { return prosta(l.s - k.s, k.f - l.f, k.f * l.s - k.s * l.f); } pair przeciecie(prosta k, prosta l) { LD det = k.B * l.A - k.A * l.B; if (iszero(det)) { return MP(0, MP(0, 0)); } return MP(1, make_pair((k.B * l.C - k.C * l.B) / det, (k.C * l.A - k.A * l.C) / det)); } bool iszero(LD x) { return abs(x) < eps; } int n; punkt p, k; VPII V; set poz, pion; vector ps; vector P; vector> po, pi; bool inside(punkt x) { int r = 0; for (auto pp : po) { if (pp.f.s > x.s && pp.f.f <= x.f && pp.s.f > x.f) { r++; } } return r % 2 == 1; } LD poziomo(punkt x, pair pp) { return max(abs(x.s - pp.f.s), max(pp.f.f - x.f, x.f - pp.s.f)); } LD pionowo(punkt x, pair pp) { return max(abs(pp.f.f - x.f), max(x.s - pp.f.s, pp.s.s - x.s)); } LD height(punkt x) { if (!inside(x)) { return 0; } LD r = inf; for (auto pp : po) { debug(x, pp, poziomo(x, pp)); mini(r, poziomo(x, pp)); } for (auto pp : pi) { debug(x, pp, pionowo(x, pp)); mini(r, pionowo(x, pp)); } return r; } int32_t main() { scanf("%d%Lf%Lf%Lf%Lf", &n, &p.f, &p.s, &k.f, &k.s); FOR(i, 1, n) { int a, b; scanf("%d%d", &a, &b); V.PB(MP(a, b)); } V.PB(V[0]); debug(V); FOR(i, 0, SIZ(V) - 2) { debug(V[i], V[i + 1]); if (V[i].f == V[i + 1].f) { pion.insert(V[i].f); pi.PB(MP(V[i], V[i + 1])); if (pi.back().f.s < pi.back().s.s) { swap(pi.back().f, pi.back().s); } } if (V[i].s == V[i + 1].s) { poz.insert(V[i].s); po.PB(MP(V[i], V[i + 1])); if (po.back().f.f > po.back().s.f) { swap(po.back().f, po.back().s); } } } debug(po, pi); VI pozz, pionn; for (auto x : poz) pozz.PB(x); for (auto x : pion) pionn.PB(x); FOR(i, 0, SIZ(pozz) - 2) { for (auto x : pionn) { LD h = (LD)(pozz[i] + pozz[i + 1]) / 2; ps.PB(MP(x - (h - pozz[i]), h)); ps.PB(MP(x + (h - pozz[i]), h)); } } FOR(i, 0, SIZ(pionn) - 2) { for (auto y : pozz) { LD d = (LD)(pionn[i] + pionn[i + 1]) / 2; ps.PB(MP(y - (d - pionn[i]), d)); ps.PB(MP(y + (d - pionn[i]), d)); } } for (auto x : V) { debug(x); P.PB(przezpunkty(x, MP(x.f + 1, x.s + 1))); P.PB(przezpunkty(x, MP(x.f + 1, x.s - 1))); P.PB(przezpunkty(x, MP(x.f + 1, x.s))); P.PB(przezpunkty(x, MP(x.f, x.s + 1))); } for (auto x : ps) { P.PB(przezpunkty(x, MP(x.f + 1, x.s + 1))); P.PB(przezpunkty(x, MP(x.f + 1, x.s - 1))); P.PB(przezpunkty(x, MP(x.f + 1, x.s))); P.PB(przezpunkty(x, MP(x.f, x.s + 1))); } prosta moja = przezpunkty(p, k); vector> przeciecia; for (auto pp : P) { pair x = przeciecie(moja, pp); if (!x.f) { continue; } if (iszero(dist(x.s, p) + dist(x.s, k) - dist(p, k))) { przeciecia.PB(MP(dist(p, x.s), x.s)); } } przeciecia.PB(MP(0, p)); przeciecia.PB(MP(dist(p, k), k)); vector hh; sort(ALL(przeciecia)); for (auto x : przeciecia) { hh.PB(height(x.s)); } LD res = 0; debug(przeciecia); debug(hh); debug("lol", height(MP(3, 2))); FOR(i, 0, SIZ(przeciecia) - 2) { LD d = dist2(przeciecia[i].s, przeciecia[i + 1].s); LD diff = abs(hh[i] - hh[i + 1]); res += sqrt(d + diff * diff); } printf("%.10Lf\n", res); }