#include #include #include #include #include #include using db = double; const db PI = db{4.0} * std::atan(db{1.0}); template struct Point { Point(T x, T y): x_(x), y_(y) {} Point& operator-=(const Point& p) { x_ -= p.x_; y_ -= p.y_; return *this; } Point operator-(const Point& p) const { return Point(*this) -= p; } db angle() const { return std::atan2(y_, x_); } // this x p db cross(const Point& p) const { return x_ * p.y_ - y_ * p.x_; } // (p - this) x (q - this) db cross(const Point& p, const Point& q) const { return (p - *this).cross(q - *this); } // u(theta) x (p - this) db cross(db theta, const Point& p) const { auto vec = p - *this; return cos(theta) * vec.y_ - sin(theta) * vec.x_; } std::optional intersection(db theta, const Point& c, const Point& d) const { Point v1{cos(theta), sin(theta)}; Point v2 = d - c; db den = v1.cross(v2); if (den == 0.0) { return {}; } Point b{x_ + v1.x_, y_ + v1.y_}; db p = c.cross(b, d); db q = c.cross(d, *this); return std::make_optional((x_ * p + b.x_ * q) / den, (y_ * p + b.y_ * q) / den); } friend std::ostream& operator<<(std::ostream& os, const Point& p) { return os << "(" << p.x_ << "," << p.y_ << ")"; } T x_, y_; }; using P = Point; std::vector

makeSquare(db n) { return { P{0.0, 0.0}, P{n, 0.0}, P{n, n}, P{0.0, n}, }; } // find the area of the nxn square on one side after you cut from chip at angle db solveLine(const std::vector

& poly, const P& chip, db theta, db n) { // Polygon clipping. For each directed edge in order, if // the two ends are on the same side of the cut line, then // add the front. Otherwise, find the intersection and add // that. static std::vector

clipped; clipped.clear(); for (int32_t i = 0; i < poly.size(); ++i) { const P& last = poly[(i + poly.size() - 1) % poly.size()]; const P& here = poly[i]; bool side1 = chip.cross(theta, last) < 0; bool side2 = chip.cross(theta, here) < 0; if (side1 != side2) { auto res = chip.intersection(theta, last, here); if (res) { clipped.push_back(*res); } } if (side2) { clipped.push_back(here); } } db area = clipped.back().cross(clipped[0]); for (int32_t i = 0; i + 1 < clipped.size(); ++i) { area += clipped[i].cross(clipped[i + 1]); } return area / 2.0 / n / n; } int main() { int32_t n, m; std::cin >> n >> m; std::vector

points; points.reserve(m); for (int32_t i = 0; i < m; ++i) { int64_t x, y; std::cin >> x >> y; points.emplace_back(static_cast(x), static_cast(y)); } auto square = makeSquare(n); db ans = 0.0; db invChips = 1.0 / m; for (int32_t i = 0; i < m; ++i) { const P& origin = points[i]; using Event = std::pair; std::vector events; events.reserve(4 * m + 4 * 4); for (int32_t j = 0; j < m; ++j) { if (i == j) continue; db ang = (points[j] - origin).angle(); events.emplace_back(ang, +1); events.emplace_back(ang + PI, -1); events.emplace_back(ang + 2 * PI, +1); events.emplace_back(ang + 3 * PI, -1); } { for (const auto& corner : square) { db theta = -(origin - corner).angle(); for (int32_t k = 0; k < 4; ++k, theta += PI / 2.0) { events.emplace_back(theta, 0); } } } std::sort(events.begin(), events.end()); int32_t chips = 1; for (auto [theta, d] : events) { if (d >= 0) { chips += d; } if (chips * invChips > ans) ans = std::max(ans, chips * invChips - solveLine(square, origin, theta, n)); if (d < 0) { chips += d; } } } std::cout << std::setprecision(15); std::cout << ans << '\n'; return 0; }