22int orientation(
const std::pair<int, int> a,
const std::pair<int, int> b,
23 const std::pair<int, int> c) {
24 double v = a.first * (b.second - c.second) + b.first * (c.second - a.second) +
25 c.first * (a.second - b.second);
36std::vector<std::pair<int, int>> graham_scan(std::vector<std::pair<int, int>> points,
37 bool include_first_twice =
true) {
39 std::pair<int, int> p0 = *min_element(
40 points.begin(), points.end(), [](std::pair<int, int> a, std::pair<int, int> b) {
41 return std::make_pair(a.second, a.first) < std::make_pair(b.second, b.first);
45 std::sort(points.begin(), points.end(),
46 [&](
const std::pair<int, int> a,
const std::pair<int, int> b) {
47 int ori = helpers::orientation(p0, a, b);
49 return (p0.first - a.first) * (p0.first - a.first) +
50 (p0.second - a.second) * (p0.second - a.second) <
51 (p0.first - b.first) * (p0.first - b.first) +
52 (p0.second - b.second) * (p0.second - b.second);
57 std::vector<std::pair<int, int>> s;
58 for (
const auto& point : points) {
59 while (s.size() > 1 && helpers::orientation(s[s.size() - 2], s.back(), point) <= 0) {
65 if (include_first_twice) {