Advertisement
Guest User

Rotating Calipers (TFOSS)

a guest
Dec 8th, 2016
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.01 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. typedef long long ll;
  5. typedef pair<ll,ll> pll;
  6.  
  7. #define x first
  8. #define y second
  9.  
  10. vector<pll> v;
  11. vector<pll> h;
  12.  
  13. ll cross(pll o, pll a, pll b) {
  14.     return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);
  15. }
  16.  
  17. ll sqr(ll x) { return x*x; }
  18.  
  19. // máximo da distância ao quadrado de a<->opo ou b<->opo
  20. ll dist(pll a, pll b, pll opo) {
  21.     return max(sqr(a.x - opo.x) + sqr(a.y - opo.y),
  22.             sqr(b.x - opo.x) + sqr(b.y - opo.y));
  23. }
  24.  
  25. int main()
  26. {
  27.     int t;
  28.     scanf("%d", &t);
  29.     while(t--) {
  30.         v.clear();
  31.         int n;
  32.         scanf("%d", &n);
  33.  
  34.         ll a,b;
  35.         for (int i = 0; i < n; i++)
  36.             scanf("%lld %lld", &a, &b), v.push_back({a,b});
  37.  
  38.         if (n == 1) { printf("%d\n", 0); continue;}
  39.  
  40.         // ordena os pontos pelo x e depois pelo y
  41.         sort(v.begin(), v.end());
  42.         h.clear();
  43.        
  44.         // acha o convex hull (upper hull + lower hull) (inclue pontos colineares)
  45.         int cnt = 0;
  46.         for (int i = 0; i < n; i++) {
  47.             while (cnt > 1 && cross(h[cnt-2], h[cnt-1], v[i]) >= 0) h.pop_back(), cnt--;
  48.             h.push_back(v[i]); cnt++;
  49.         }
  50.  
  51.         int cnt0 = cnt;
  52.  
  53.         for (int i = n-2; i >= 0; i--) {
  54.             while (cnt - cnt0 > 0 && cross(h[cnt-2], h[cnt-1], v[i]) >= 0) h.pop_back(), cnt--;
  55.             h.push_back(v[i]); cnt++;
  56.         }
  57.  
  58.         // faz rotating calipers e atualiza resposta
  59.         ll ans = 0;
  60.         int opo = 1;
  61.         // itera pelos pontos:
  62.         for (int i = 1; i < h.size(); i++) {
  63.             // atualiza a reta oposta (par de pontos que definem a reta);
  64.             while (1) {
  65.                 int next = opo+1 < h.size() ? opo+1 : 1;
  66.                 if (dist(h[i-1], h[i], h[opo]) <= dist(h[i-1], h[i], h[next]))
  67.                     opo = next;
  68.                 else
  69.                     break;
  70.             }
  71.  
  72.             ans = max(ans, dist(h[i], h[i-1], h[opo]));
  73.         }
  74.  
  75.         printf("%lld\n", ans);
  76.     }
  77. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement