DuongNhi99

CONVEXHULL (Bao lồi)

Jan 3rd, 2022 (edited)
196
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.79 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. using ll = long long;
  5. using ld = long double;
  6. using pii = pair<int, int>;
  7.  
  8. const int maxN = 1e5 + 5;
  9. const int INF = 1e9 + 7;
  10.  
  11. struct point {
  12.     long long x, y;
  13. };
  14.  
  15. bool xetx(point a, point b) { return (a.x < b.x) || (a.x == b.x && a.y < b.y); }
  16. bool xety(point a, point b) { return (a.y < b.y) || (a.y == b.y && a.x < b.x); }
  17.  
  18. bool CW(point a, point b, point c) { // Cùng chiều kim đồng hồ
  19.     return a.x*(c.y-b.y) + b.x*(a.y-c.y) + c.x*(b.y-a.y) > 0;
  20. }
  21.  
  22. bool CCW(point a, point b, point c) { // Ngược chiều kim đồng hồ
  23.     return a.x*(c.y-b.y) + b.x*(a.y-c.y) + c.x*(b.y-a.y) < 0;
  24. }
  25.  
  26. long double Sdagiac(vector<point> &a) {
  27.     long double x = 1.0;
  28.     long double S = 0.0;
  29.     a[a.size()] = a[0];
  30.     for (int i = 0; i < a.size(); ++i)
  31.         S += x * (a[i+1].x - a[i].x) * (a[i+1].y + a[i].y);
  32.     return (S > 0) ? (S / 2.0) : (-S / 2.0);
  33. }
  34.  
  35. void CONVEXHULL(vector<point> &a) {
  36.     if (a.size() == 1)
  37.         return;
  38.  
  39.     sort (a.begin(), a.end(), &xetx);
  40.  
  41.     point p1 = a[0], p2 = a.back();
  42.  
  43.     vector<point> up, down;
  44.     up.push_back(p1);
  45.     down.push_back(p1);
  46.  
  47.     for (size_t i = 1; i < a.size(); ++i) {
  48.         // Chuỗi trên
  49.         if (i == a.size()-1 || CW(p1, a[i], p2)) {
  50.             while (up.size() >= 2 && !CW(up[up.size()-2], up[up.size()-1], a[i]))
  51.                 up.pop_back();
  52.             up.push_back(a[i]);
  53.         }
  54.  
  55.         // Chuỗi dưới
  56.         if (i == a.size()-1 || CCW(p1, a[i], p2)) {
  57.             while (down.size() >= 2 && !CCW(down[down.size()-2], down[down.size()-1], a[i]))
  58.                 down.pop_back();
  59.             down.push_back(a[i]);
  60.         }
  61.     }
  62.  
  63.     // Gộp 2 chuỗi
  64.     a.clear();
  65.     for (int i = 0; i < down.size()-1; ++i)
  66.         a.push_back(down[i]);
  67.     for (int i = up.size()-1; i > 0; --i)
  68.         a.push_back(up[i]);
  69.  
  70.     // In đáp án
  71.     long long ans = a.size();
  72.  
  73.     cout << ans << '\n';
  74.     cout << fixed << setprecision(1) << Sdagiac(a) << '\n';
  75.  
  76.     long long mx = INF, my = INF, id = -1;
  77.     for (int i = 0; i < ans; ++i)
  78.         my = min(my, a[i].y);
  79.     for (int i = 0; i < a.size(); ++i)
  80.         if (a[i].y == my && mx > a[i].x)
  81.             mx = a[i].x, id = i;
  82.     for (int i = 0; i < ans; ++i) {
  83.         cout << a[id%ans].x << ' ' << a[id%ans].y << '\n';
  84.         ++id;
  85.     }
  86. }
  87.  
  88. int n;
  89. vector<point> Points;
  90.  
  91. int main() {
  92. #ifdef LOCAL
  93.     freopen("in2.txt", "r", stdin);
  94. #else
  95.     freopen("CONVEXHULL.inp", "r", stdin);
  96.     freopen("CONVEXHULL.out", "w", stdout);
  97. #endif
  98.     ios_base::sync_with_stdio(false);
  99.     cin.tie(nullptr);
  100.  
  101.     cin >> n;
  102.     for (int i = 0; i < n; i++) {
  103.         point a; cin >> a.x >> a.y;
  104.         Points.push_back(a);
  105.     }
  106.  
  107.     CONVEXHULL(Points);
  108.  
  109.     return 0;
  110. }
  111.  
Advertisement
Add Comment
Please, Sign In to add comment