1
+ #include < bits/stdc++.h>
2
+ using namespace std ;
3
+ typedef long long ll;
4
+
5
+ struct Po {
6
+ typedef Po P;
7
+ ll x, y, idx;
8
+ Po (ll x = 0 , ll y = 0 ) : x(x), y(y) {}
9
+ bool operator ==(P t) const { return x == t.x && y == t.y ; }
10
+ P operator -(P p) const { return P (x - p.x , y - p.y ); }
11
+ ll cross (P p) const { return x * p.y - y * p.x ; }
12
+ ll cross (P a, P b) const { return (a - *this ).cross (b - *this ); }
13
+ friend ostream &operator <<(ostream &os, P p) {
14
+ return os << p.x << " " << p.y << " \n " ;
15
+ }
16
+ };
17
+
18
+ void solve () {
19
+ int n;
20
+ cin >> n;
21
+ vector<Po> v (n);
22
+ for (int i = 0 ; i < n; i++) {
23
+ cin >> v[i].x >> v[i].y ;
24
+ v[i].idx = i;
25
+ }
26
+
27
+ vector<Po> convex_hull;
28
+
29
+ auto getlast2 = [&]() {
30
+ auto x = *(convex_hull.end () - 2 ), y = *(convex_hull.end () - 1 );
31
+ return make_tuple (x, y);
32
+ };
33
+
34
+ auto check = [&](Po z) {
35
+ auto [x, y] = getlast2 ();
36
+ return x.cross (y, z) <= 0 ;
37
+ };
38
+
39
+ // construct upper hull
40
+ sort (v.begin (), v.end (),
41
+ [](Po a, Po b) { return a.x == b.x ? a.y > b.y : a.x < b.x ; });
42
+ for (auto cur : v) {
43
+ while (convex_hull.size () >= 2 && !check (cur)) convex_hull.pop_back ();
44
+ convex_hull.push_back (cur);
45
+ }
46
+
47
+ // construct lower hull
48
+ reverse (v.begin (), v.end ());
49
+ convex_hull.pop_back ();
50
+ int s = convex_hull.size ();
51
+ for (auto cur : v) {
52
+ while (convex_hull.size () - s >= 2 && !check (cur)) convex_hull.pop_back ();
53
+ convex_hull.push_back (cur);
54
+ }
55
+ convex_hull.pop_back ();
56
+
57
+ cout << convex_hull.size () << " \n " ;
58
+ for (auto i : convex_hull) cout << i;
59
+ }
60
+
61
+ int main () {
62
+ ios::sync_with_stdio (false );
63
+ cin.tie (0 );
64
+ cout.tie (0 );
65
+
66
+ int t = 1 ;
67
+ // cin >> t;
68
+ while (t--) solve ();
69
+ }
0 commit comments