AlexNeagu11

Birthday Cake

Feb 25th, 2023 (edited)
704
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.20 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. // #define int long long
  3. #define f first
  4. #define s second
  5. using namespace std;
  6.  
  7. typedef long long ll;
  8. const int MOD = 1e9 + 9;
  9. const int inf = 1e9;
  10. const double eps = 1e-9;
  11. const double PI = acos(-1);
  12.  
  13.  
  14. struct point {
  15.     ll x, y;
  16.     point operator - (const point &p) const {
  17.         return point{x - p.x, y - p.y};
  18.     }
  19.     point operator *(ll d) {
  20.         return {x * d, y * d};
  21.     }
  22.     ll operator *(const point &p) {
  23.         return x * p.y - y * p.x;
  24.     }
  25.     bool isRight(point &P) {
  26.         if(P.x > 0) {
  27.             return true;
  28.         }
  29.         return (P.x == 0 && P.y < 0);
  30.     }
  31.     bool operator < (point &p) {
  32.         if(isRight(*this) != isRight(p)) {
  33.             return isRight(*this);
  34.         }
  35.         return *this * p > 0;  
  36.     }
  37.     bool operator == (point &p) {
  38.         return (x == p.x && y == p.y);
  39.     }
  40.     void read() {
  41.         double X, Y;
  42.         cin >> X >> Y;
  43.         x = llround(X * 1e6);
  44.         y = llround(Y * 1e6);
  45.     }
  46. };
  47.  
  48. ll orient(point o, point a, point b) {
  49.     return (a - o) * (b - o);
  50. }
  51.  
  52. ostream& operator << (ostream& os, const point &p) {
  53.     return os << "(" << p.x << "," << p.y << ")";
  54. }
  55.  
  56. void insert(vector<point> &hull, point &P) {
  57.     while(hull.size() > 1) {
  58.         int sz = hull.size();
  59.         if(orient(hull[sz - 2], hull[sz - 1], P) >= 0) {
  60.             hull.pop_back();
  61.         }
  62.         else {
  63.             break;
  64.         }
  65.     }
  66.     hull.push_back(P);
  67. }
  68.  
  69. vector<point> compute_hull(vector<point> &red) {
  70.     if(red.size() == 1) {
  71.         return red;
  72.     }
  73.     vector<point> upper;
  74.     int m = red.size();
  75.     for(int i = 0; i < m; ++i) {
  76.         insert(upper, red[i]);
  77.     }
  78.     upper.pop_back();
  79.  
  80.     vector<point> lower;
  81.     for(int i = m - 1; i >= 0; --i) {
  82.         insert(lower, red[i]);
  83.     }
  84.     lower.pop_back();
  85.    
  86.     vector<point> ans;
  87.     for(auto it: upper) {
  88.         ans.push_back(it);
  89.     }
  90.     for(auto it: lower) {
  91.         ans.push_back(it);
  92.     }
  93.     return ans;
  94. }
  95.  
  96. bool same_sign(ll a, ll b) {
  97.     return ((a <= 0 && b <= 0) || (a >= 0 && b >= 0));
  98. }
  99. bool between(point &angle, point &left_vec, point &right_vec) {
  100.     return (same_sign(left_vec * angle, left_vec * right_vec)
  101.             && same_sign(right_vec * angle, right_vec * left_vec));
  102. }
  103.  
  104. int n, m;
  105. vector<point> red, blue;
  106.  
  107. int main() {
  108.     ios_base::sync_with_stdio(false);
  109.     cin.tie(0);
  110.  
  111.     cin >> n >> m;
  112.  
  113.     blue.resize(n);
  114.     red.resize(m);
  115.  
  116.     for(int i = 0; i < n; ++i) {
  117.         blue[i].read();
  118.     }
  119.  
  120.     for(int i = 0; i < m; ++i) {
  121.         red[i].read();
  122.     }
  123.    
  124.     sort(red.begin(), red.end(), [&](point &a, point &b) {
  125.         if(a.x == b.x) {
  126.             return a.y < b.y;
  127.         }
  128.         return a.x < b.x;
  129.     });
  130.  
  131.     vector<point> polygon = compute_hull(red);
  132.     int N = polygon.size();
  133.  
  134.     int ans = 0;
  135.  
  136.     for(int i = 0; i < N; ++i) {
  137.         point right_vec = polygon[(i + 1) % N] - polygon[i];
  138.         point left_vec = (polygon[(i - 1 + N) % N] - polygon[i]);
  139.         vector<point> angles;
  140.         if(N == 2) {
  141.             left_vec = right_vec * -1;
  142.         }
  143.         for(auto y: blue) {
  144.             point angle = y - polygon[i];
  145.             if(N <= 2) {
  146.                 angles.push_back(angle);
  147.             }
  148.             else if(!between(angle, left_vec, right_vec)) {
  149.                 // points that are not between vectors
  150.                 angles.push_back(angle);
  151.             }
  152.         }
  153.        
  154.         if(N > 1) {
  155.             angles.push_back(left_vec);
  156.             angles.push_back(right_vec);
  157.         }
  158.         sort(angles.begin(), angles.end());
  159.         int M = angles.size();
  160.  
  161.         for(int i = 0; i < M; ++i) {
  162.             angles.push_back(angles[i]);
  163.         }
  164.        
  165.         int R = 0;
  166.         for(int L = 0; L < M; ++L) {
  167.             if(R < L) {
  168.                 R = L;
  169.             }
  170.             while(R == L || ((angles[L] * angles[R] > 0))) {
  171.                 if(angles[R] == left_vec || angles[R] == right_vec) {
  172.                     break;
  173.                 }
  174.                 R++;
  175.             }
  176.             ans = max(ans, max(0, R - L));
  177.         }
  178.     }
  179.  
  180.     cout << ans << '\n';
  181.     return 0;
  182. }
Advertisement
Add Comment
Please, Sign In to add comment