1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
| #include <bits/stdc++.h> #define fi first #define se second using DB = double; using PDD = std::pair<double, double>; const int N = 50000 + 100; const DB eps = 1e-12; int stk[N], top; bool vis[N]; DB ans = 1e18; std::array<PDD, 4> as; int cmp(DB x, DB y) { if (fabs(x - y) < eps) return 0; return x > y ? 1 : -1; } PDD operator - (PDD x, PDD y){ return {x.fi - y.fi, x.se - y.se}; } PDD operator + (PDD x, PDD y){ return {x.fi + y.fi, x.se + y.se}; } PDD operator / (PDD x, DB y){ return {x.fi / y, x.se / y}; }PDD operator * (PDD x, DB y){ return {x.fi * y, x.se * y}; } DB operator * (PDD x, PDD y){ return x.fi * y.se - x.se * y.fi; } DB operator & (PDD x, PDD y){ return x.fi * y.fi + x.se * y.se; } DB area(PDD x, PDD y, PDD z){ return (y - x) * (z - x); } DB mo(PDD x){ return std::sqrt(x & x); } DB proj(PDD x, PDD y, PDD z) { y = y - x, z = z - x; return y & z / mo(y); } PDD rot(PDD x, DB th){ return {x.fi * std::cos(th) + x.se * std::sin(th), -x.fi * std::sin(th) + x.se * std::cos(th)}; } PDD norm(PDD x){ return x / mo(x); } void convex(PDD *x, int n) { top = 0; std::sort(x, x + n); for (int i = 0; i < n; ++i) { while (top >= 2) { int t = cmp(area(x[stk[top - 2]], x[stk[top - 1]], x[i]), 0); if (t < 0) vis[stk[--top]] = false; else if (!t) --top; else break; } vis[stk[top++] = i] = true; } vis[0] = false; for (int i = n - 1; ~i; --i) if (!vis[i]) { while (top >= 2 && cmp(area(x[stk[top - 2]], x[stk[top - 1]], x[i]), 0) < 0) --top; stk[top++] = i; } --top; } void rotcal(PDD *x, int n) { for (int i = 0, a = 2, b = 1, c; i < top; ++i) { PDD d = x[stk[i]], e = x[stk[i + 1]]; while (cmp(area(d, e, x[stk[a]]), area(d, e, x[stk[a + 1]])) < 0) a = a + 1 >= top ? 0 : a + 1; while (cmp(proj(d, e, x[stk[b]]), proj(d, e, x[stk[b + 1]])) < 0) b = b + 1 >= top ? 0 : b + 1; if (!i) c = a; while (cmp(proj(d, e, x[stk[c]]), proj(d, e, x[stk[c + 1]])) > 0) c = c + 1 >= top ? 0 : c + 1; PDD ta = x[stk[a]], tb = x[stk[b]], tc = x[stk[c]]; DB h = area(d, e, ta) / mo(e - d); DB w = proj(d, e, tb) - proj(d, e, tc); if (cmp(w * h, ans) < 0) { ans = w * h; as[0]= d + norm(e - d) * proj(d, e, tb); as[3] = d + norm(e - d) * proj(d, e, tc); PDD u = norm(rot(e - d, -M_PI / 2)); as[1] = as[0]+ u * h; as[2] = as[3] + u * h; } } } int main() { int n, k = 0; PDD a[N]; scanf("%d", &n); for (int i = 0; i < n; ++i) scanf("%lf %lf", &a[i].fi, &a[i].se); convex(a, n), rotcal(a, n); for (int i = 1; i < 4; ++i) if (cmp(as[i].se, as[k].se) < 0 || (!cmp(as[i].se, as[k].se) && cmp(as[i].fi, as[k].fi) < 0)) k = i; printf("%.5lf\n", ans); for (int i = 0; i < 4; ++i, k = k + 1 >= 4 ? 0 : k + 1) { if (!cmp(as[k].fi, 0)) as[k].fi = 0; if (!cmp(as[k].se, 0)) as[k].se = 0; printf("%.5lf %.5lf\n", as[k].fi, as[k].se); } return 0; }
|