Advertisement
cosenza987

Untitled

Jan 28th, 2023
690
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.40 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. #define st first
  6. #define nd second
  7. #define db(x) cerr << #x << " == " << x << endl
  8. #define _ << ", " <<
  9.  
  10. typedef long long ll;
  11. typedef long double ld;
  12. typedef pair<int, int> pii;
  13.  
  14. const ld EPS = 1e-6, PI = acos(-1.);
  15. const ll LINF = 0x3f3f3f3f3f3f3f3f;
  16. const int INF = 0x3f3f3f3f, MOD = 1e9 + 7;
  17. const int N = 1e5 + 5;
  18.  
  19. typedef long long type;
  20.  
  21. bool ge(ld x, ld y) { return x + EPS > y; }
  22. bool le(ld x, ld y) { return x - EPS < y; }
  23.  
  24. struct point {
  25.     type x, y;
  26.     point(): x(0), y(0) {}
  27.     point(type _x, type _y): x(_x), y(_y) {}
  28.  
  29.     point operator -() { return point(-x, -y); }
  30.     point operator +(point p) { return point(x + p.x, y + p.y); }
  31.     point operator -(point p) { return point(x - p.x, y - p.y); }
  32.  
  33.     point operator *(type k) { return point(x * k, y * k); }
  34.     point operator /(type k) { return point(x / k, y / k); }
  35.  
  36.     type operator %(point p) { return x * p.y - y * p.x; }
  37.  
  38.     bool operator ==(const point& p) const { return x == p.x and y == p.y; }
  39.     bool operator !=(const point& p) const { return x != p.x or y != p.y; }
  40.     bool operator <(const point& p) const { return (x < p.x) or (x == p.x and y < p.y); }
  41.  
  42.     int dir(point o, point p) {
  43.         type x = (*this - o) % (p - o);
  44.         return (x >= 0) - (x <= 0);
  45.     }
  46. };
  47.  
  48. point rotate_cw90(point p) { return point(p.y, -p.x); }
  49.  
  50. ostream& operator<<(ostream& os, const point& p) {
  51.     os << "(" << p.x << "," << p.y << ")";
  52.     return os;
  53. }
  54.  
  55. point origin;
  56.  
  57. int above(point p) {
  58.     if (p.y == origin.y) return p.x > origin.x;
  59.     return p.y > origin.y;
  60. }
  61.  
  62. bool cmp(pair<point, point> a, pair<point, point> b) {
  63.     point p = rotate_cw90(a.nd - a.st);
  64.     point q = rotate_cw90(b.nd - b.st);
  65.  
  66.     int tmp = above(q) - above(p);
  67.     if (tmp) return tmp > 0;
  68.     if (p.dir(origin, q) == 0) {
  69.         if (a.nd.dir(a.st, b.st) == 0) {
  70.             if (a.st == b.st) return a.nd < b.nd;
  71.             return a.st < b.st;
  72.         }
  73.         return a.nd.dir(a.st, b.st) > 0;
  74.     }
  75.     return p.dir(origin, q) > 0;
  76. }
  77.  
  78. ld compute_area(vector<pair<ld, ld>>& p) {
  79.     ld area = 0;
  80.     for (int i = 0; i < p.size(); i++) {
  81.         int j = (i + 1) % p.size();
  82.         area += p[i].st * p[j].nd - p[j].st * p[i].nd;
  83.     }
  84.     return fabs(area / 2);
  85. }
  86.  
  87. int n;
  88. ll sz;
  89. map<point, int> id;
  90.  
  91. ld calc_area(point p1, point p2) {
  92.     pair<ld, ld> a, b;
  93.     if (p1.x == p2.x) {
  94.         return (ld)sz * (sz - p1.x);
  95.     }
  96.     else if (p1.y == p2.y) {
  97.         return (ld)p1.y * sz;
  98.     }
  99.     else {
  100.         vector<pair<ld, ld>> p;
  101.         ld m_coef = (ld)(p2.y - p1.y) / (ld)(p2.x - p1.x);
  102.         ld n_coef = (p1.y - m_coef * p1.x);
  103.         a = { 0, n_coef }, b = { sz, sz * m_coef + n_coef };
  104.         if (le(m_coef, 0)) {
  105.             p.push_back({ 0, 0 });
  106.  
  107.             //y = mx + n
  108.             //top left
  109.             if (ge(n_coef, sz)) p.push_back({ 0, sz }), p.push_back({ (sz - n_coef) / m_coef, sz });
  110.             else p.push_back({ 0, n_coef });
  111.  
  112.             //bottom right
  113.             if (ge(-n_coef / m_coef, sz)) p.push_back({ sz, m_coef * sz + n_coef }), p.push_back({ sz, 0 });
  114.             else p.push_back({ -n_coef / m_coef, 0 });
  115.         }
  116.         else {
  117.             //y = mx + n
  118.             //bottom left
  119.             if (ge(n_coef, 0)) p.push_back({ 0, 0 }), p.push_back({ 0, n_coef });
  120.             else p.push_back({ -n_coef / m_coef, 0 });
  121.  
  122.             //top right
  123.             if (ge(m_coef * sz + n_coef, sz))  p.push_back({ (sz - n_coef) / m_coef, sz }), p.push_back({ sz, sz });
  124.             else p.push_back({ sz, m_coef * sz + n_coef });
  125.  
  126.             p.push_back({ sz, 0 });
  127.         }
  128.         return compute_area(p);
  129.     }
  130. }
  131.  
  132. int main() {
  133.     ios_base::sync_with_stdio(false);
  134.     cin.tie(NULL);
  135.     cin >> sz >> n;
  136.     vector<point> pts(n);
  137.     for (int i = 0; i < n; i++) {
  138.         cin >> pts[i].x >> pts[i].y;
  139.     }
  140.     if(n == 1) {
  141.         ld area = min({calc_area(pts[0], {0, sz}), calc_area(pts[0], {sz, 0})});
  142.         area = min({area, calc_area(pts[0], {0, 0}), calc_area(pts[0], {sz, sz})});
  143.         area = min(area, (ld)sz * (sz - pts[0].x));
  144.         area = min(area, (ld)sz * pts[0].x);
  145.         area = min(area, (ld)sz * (sz - pts[0].y));
  146.         area = min(area, (ld)sz * pts[0].y);
  147.         cout << setprecision(20) << fixed << (1.0 - area / (sz * sz));
  148.         return 0;
  149.     }
  150.     //sort points
  151.     sort(pts.begin(), pts.end());
  152.     for (int i = 0; i < n; i++) {
  153.         point p = pts[i];
  154.         id[p] = i;
  155.     }
  156.     //create edges and sort perpendicular radially
  157.     vector<pair<point, point>> edges;
  158.     for (int i = 0; i < n; i++) {
  159.         for (int j = i + 1; j < n; j++) {
  160.             edges.push_back({ pts[i], pts[j] });
  161.         }
  162.     }
  163.     sort(edges.begin(), edges.end(), cmp);
  164.     ld ans = -LINF;
  165.     //radial sweep
  166.     for (auto e : edges) {
  167.         int l = id[e.st], r = id[e.nd];
  168.         //process
  169.         int l_cookie = l, r_cookie = n - r - 1;
  170.         ld below_area = calc_area(e.st, e.nd);
  171.         //below calc
  172.         ld tmp = (ld)(l_cookie + 2) / ((ld)n) - (below_area / (sz * sz));
  173.         ans = max(ans, tmp);
  174.         //upper calc
  175.         tmp = (ld)(r_cookie + 2) / ((ld)n) - ((sz * sz - below_area) / (sz * sz));
  176.         ans = max(ans, tmp);
  177.         swap(pts[l], pts[r]);
  178.         swap(id[e.nd], id[e.st]);
  179.     }
  180.     cout << setprecision(20) << fixed << ans << "\n";
  181.     return 0;
  182. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement