#include #include #include #include #include #include #include using namespace std; typedef pair PII; typedef vector VI; typedef vector> VII; template ostream& operator<<(ostream& os, pair &p) { os << "(" << p.first << ", " << p.second << ")"; return os; } template void print(vector sez) { for (T x : sez) cout << x << " "; cout << endl; } PII operator-(PII a, PII b) { return {a.first-b.first, a.second-b.second}; } int cross(PII a, PII b) { return a.first*b.second - a.second*b.first; } vector graham_scan(vector points) { int n=points.size(); PII t=*min_element(points.begin(), points.end()); vector> angles; for (PII p : points) if (p!=t) { PII v=p-t; // t->p double a=atan2(v.second, v.first); angles.push_back({a, p}); } sort(angles.begin(),angles.end()); vector hull = {t}; for (auto [_, p] : angles) { // doda novo tocko while (hull.size()>=2) { // popravi konveksnost PII a=hull[hull.size()-2], b=hull[hull.size()-1]; PII ab=b-a, ap=p-a; if (cross(ab, ap) > 0) break; hull.pop_back(); } hull.push_back(p); } return hull; } int main() { vector points = {{4,0}, {2,3}, {5,2}, {6,1}, {8,4}, {6,6}, {5,4}, {4,5}, {2,6}, {1,1}, {1,5}, {3,2}}; auto hull = graham_scan(points); print(hull); return 0; }