-
Notifications
You must be signed in to change notification settings - Fork 9
/
graham_scan.cpp
60 lines (50 loc) · 1.42 KB
/
graham_scan.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// graham_scan.cpp
// Eric K. Zhang; Nov. 22, 2017
// Reads a number N (1 <= N <= 3 * 10^5), then N pairs
// of integers (X, Y). Outputs the convex hull of these
// points in O(N log N) time, without including middle
// points that are collinear.
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> point;
#define MAXN 300000
int N;
point points[MAXN];
LL ccw(point a, point b, point c) {
return (LL) (b.first - a.first) * (c.second - a.second)
- (LL) (b.second - a.second) * (c.first - a.first);
}
vector<point> graham_scan(vector<point> points) {
int N = points.size();
sort(points.begin(), points.end());
vector<point> hull(N + 1);
int idx = 0;
for (int i = 0; i < N; i++) {
while (idx >= 2 && ccw(hull[idx - 2], hull[idx - 1], points[i]) >= 0)
idx--;
hull[idx++] = points[i];
}
int half = idx;
for (int i = N - 2; i >= 0; i--) {
while (idx > half && ccw(hull[idx - 2], hull[idx - 1], points[i]) >= 0)
idx--;
hull[idx++] = points[i];
}
idx--;
hull.resize(idx);
return hull;
}
int main() {
vector<point> points = {
{44, 140}, {67, 153}, {69, 128}, {21, 111},
{95, 149}, {132, 119}, {103, 123}, {68, 95},
{33, 77}, {6, 51}, {53, 24}, {85, 47},
{115, 96}, {138, 73}, {129, 31}, {110, 11}
};
vector<point> hull = graham_scan(points);
for (int i = 0; i < hull.size(); i++) {
cout << '(' << hull[i].first << ", " << hull[i].second << ')' << endl;
}
return 0;
}