cosenza987

Untitled

Oct 18th, 2025
1,545
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.52 KB | None | 0 0
  1. //Слава Україні, Героям слава
  2.  
  3. #include <bits/stdc++.h>
  4.  
  5. using namespace std;
  6.  
  7. using ll = long long;
  8.  
  9. struct point {
  10.     ll x, y;
  11.     point(ll x_ = 0, ll y_ = 0) : x(x_), y(y_) {}
  12.     point operator -(point p) {
  13.         return point(x - p.x, y - p.y);
  14.     }
  15.     bool operator == (const point &p) const {
  16.         return x == p.x and y == p.y;
  17.     }
  18.     bool operator < (const point &p) const {
  19.         return (x < p.x) or (x == p.x and y < p.y);
  20.     }
  21.     ll operator %(point p) {
  22.         return x * p.y - y * p.x;
  23.     }
  24.     bool on_seg(point p, point q) {
  25.         if(this->dir(p, q)) return false;
  26.         return (x > min(p.x, q.x)) and (x < max(p.x, q.x)) and (y > min(p.y, q.y)) and (y < max(p.y, q.y));
  27.     }
  28.     long double dist (const point &p) const {
  29.         return hypotl(x - p.x, y - p.y);
  30.     }
  31.     ll dist2 (const point &p) const {
  32.         return (x - p.x) * (x - p.x) + (y - p.y) * (y - p.y);
  33.     }
  34.     int dir(point origin, point other) {
  35.         ll d = (*this - origin) % (other - origin);
  36.         return (d > 0) - (d < 0);
  37.     }
  38. };
  39.  
  40. ll cross(point p, point q) {
  41.     return p.x * q.y - p.y * q.x;
  42. }
  43.  
  44. ll area_2(point a, point b, point c) {
  45.     return cross(a, b) + cross(b, c) + cross(c, a);
  46. }
  47.  
  48. void monotone_hull(vector<point> &pts) {
  49.     sort(pts.begin(), pts.end());
  50.     pts.erase(unique(pts.begin(), pts.end()), pts.end());
  51.     vector<point> up, dn;
  52.     for(int i = 0; i < pts.size(); i++) {
  53.         while(up.size() > 1 and area_2(up[up.size() - 2], up.back(), pts[i]) > 0) up.pop_back();
  54.         while(dn.size() > 1 and area_2(dn[dn.size() - 2], dn.back(), pts[i]) < 0) dn.pop_back();
  55.         dn.push_back(pts[i]);
  56.         up.push_back(pts[i]);
  57.     }
  58.     pts = dn;
  59.     for(int i = (int)up.size() - 2; i >= 1; i--) {
  60.         pts.push_back(up[i]);
  61.     }
  62. }
  63.  
  64. int direction(point origin, point p, point other) {
  65.     return p.dir(origin, other);
  66. }
  67.  
  68. bool segment_segment_intersect(point a, point b, point c, point d) {
  69.     if(a.dist2(c) == 0 or a.dist2(d) == 0 or b.dist2(c) == 0 or b.dist2(d) == 0) return true;
  70.     ll d1 = direction(a, b, c);
  71.     ll d2 = direction(a, b, d);
  72.     ll d3 = direction(c, d, a);
  73.     ll d4 = direction(c, d, b);
  74.     if(d1 * d2 < 0 and d3 * d4 < 0) return true;
  75.     return a.on_seg(c, d) or b.on_seg(c, d) or c.on_seg(a, b) or d.on_seg(a, b);
  76. }
  77.  
  78. int main() {
  79.     ios_base::sync_with_stdio(false);
  80.     cin.tie(nullptr);
  81.     cout << setprecision(6) << fixed;
  82.     int t;
  83.     cin >> t;
  84.     while(t--) {
  85.         int n;
  86.         cin >> n;
  87.         vector<pair<array<point, 4>, int>> v(n);
  88.         vector<point> pts;
  89.         for(auto &[arr, h] : v) {
  90.             for(int i = 0; i < 4; i++) {
  91.                 cin >> arr[i].x >> arr[i].y;
  92.                 pts.emplace_back(arr[i]);
  93.             }
  94.             cin >> h;
  95.         }
  96.         monotone_hull(pts);
  97.         long double perimeter = 0;
  98.         for(int i = 0; i < (int)pts.size(); i++) {
  99.             perimeter += pts[i].dist(pts[(i + 1) % pts.size()]);
  100.         }
  101.         int h = 3;
  102.         for(int i = 0; i < (int)pts.size(); i++) for(int j = i + 1; j < (int)pts.size(); j++) {
  103.             for(int k = 0; k < n; k++) {
  104.                 for(int ii = 0; ii < 4; ii++) for(int jj = ii + 1; jj < 4; jj++) {
  105.                     if(segment_segment_intersect(pts[i], pts[j], v[k].first[ii], v[k].first[jj])) {
  106.                         h = max(h, v[k].second + 1);
  107.                     }
  108.                 }
  109.             }
  110.         }
  111.         cout << perimeter << " " << h << "\n";
  112.     }
  113.     return 0;
  114. }
Advertisement
Add Comment
Please, Sign In to add comment