๊ณจ๋1 : ๊ธฐํ ๋ฌธ์ ์ด๋ค.
์๊ฐ
๋ณผ๋ก ๊ป์ง, Convex Hull์ด๋ผ ํ๋ค. ์ด ์๊ณ ๋ฆฌ์ฆ์์ ์ ๋ช ํ ๊ฒ์ ๊ทธ๋ผํจ ์ค์บ ์๊ณ ๋ฆฌ์ฆ์ธ๋ฐ, ํด๋น ๋์์์ ๋ด๋ณด์.
์ด๊ฒ๊ณผ ๊ฐ์ ์๊ณ ๋ฆฌ์ฆ์ ๊ตฌํํ๊ธฐ ์ํด์๋ ๋ค์๊ณผ ๊ฐ์ ์ ์ฐจ๋ฅผ ๊ฑฐ์ณ์ผ ํ๋ค.
- ๊ฐ์ฅ y๊ฐ ์์ ์ ์ ๊ตฌํ๋ค.
- ๊ทธ ์ ์ ๊ธฐ์ค์ผ๋ก ์ง์ ์ ๊ฐ์ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌํ๋ค.
- ๊ฐ์ด ๊ฐ์ฅ ์์ ์ ๋ถํฐ ์กฐ์ฌํ๋ฉด์ ๋ณผ๋ก ๊ป์ง์ธ์ง ์๋์ง ํ์ธํ๊ณ ์ถ๊ฐํ๋ค.
์ด ๋, ๊ฐ์ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌ์ ์ํํด์ผ ํ๋๋ฐ, ๊ฐ์ double ํ์ด๋ผ ์ด๋ฅผ ์ ๋ ฌํ๋๋ฐ ์ข์ง ์๋ค. ์ผ๋จ ๊ตฌํ๊ธฐ๋ ์ด๋ ต๊ณ ๊ฐ์ ์ ์์ ์์ ๋ ๊ณจ์น๊ฐ ์ํ๋ค..
๊ทธ๋์ ์ด ๋ ๊ฐ์ ๋๋ณํด ์ค ์ ์๋ ๋ค๋ฅธ ์งํ๋ก ์ธ์ ์ ๋ถํธ๋ฅผ ์ฌ์ฉํ๋ค. ์ด ๋ถ๋ถ์ด ๋ฌ๋ฌํ ๋ถ๋ถ์ธ๋ฐ, ์ธ์ ์ ๊ฐ์ x, y์ถ์ ๊ธฐ์ ๋ก ๋ณด์์ ๋, ์๊ณ ๋ฐฉํฅ, ๋ฐ์๊ณ ๋ฐฉํฅ์ ๋๋ณํด ์ค๋ค. ์ด ๋, ํน์  ๋ ์ ๊ณผ์ ์ธ์ ์ ์ํํ๋ฉด ์๋ก์ ์๋์  ์์น๋ฅผ ์ ์ ์๋ค.

์ด ์ฐ์ฐ์ ์ ๋ค์ ๊ฐ ์์๋ก ์ ๋ ฌํ๋ ๋น๊ต ์ฐ์ฐ์ผ๋ก ์ฌ์ฉํ์.
Code
#include<iostream>
#include<vector>
#include<string>
#include<cstring>
#include<iomanip>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
struct Point{
    ll x, y;
};
vector<Point> p;
int N;
 
ll ccw(Point p1, Point p2, Point p3){
    return p1.x*p2.y + p2.x*p3.y + p3.x*p1.y - (p2.x*p1.y + p3.x*p2.y + p1.x*p3.y);
}
 
bool compareMinelement(Point p1, Point p2){
    if (p1.y == p2.y) return p1.x < p2.x;
    else return p1.y < p2.y;
}
 
bool compareCCW(Point p1, Point p2){
    ll cp = ccw(p[0], p1, p2);
    if (cp == 0) return (p1.x + p1.y) < (p2.x + p2.y);
    return cp > 0;
}
 
 
 
int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
    cin >> N;
    p.resize(N);
 
    for (int i = 0; i < N; i++) {
        cin >> p[i].x >> p[i].y;
    }
 
    sort(p.begin(), p.end(), compareMinelement);
    sort(p.begin()+1, p.end(), compareCCW);
 
    vector<Point> v;
    v.push_back(p[0]);
    v.push_back(p[1]);
 
    // ์ด for๋ฌธ์ ์ธ์  ์ค ๊ฐ์ฅ ๋ฐ๊นฅ์ชฝ ์ ์ ์๋ฏธ
    for (int i = 2; i < N; i++) {
        // ๋ณผ๋ก์ ์ฐพ์ ๋๊น์ง ๊ณ์ ์งํ
        while (v.size() >= 2) {
            // ๋๊ฐ๋ฅผ ๋ณธ๋ค.
            Point p2 = v.back();
            v.pop_back();
            Point p1 = v.back();
            // ccw์ด๋ฉด ์ค๊ฐ์ ์๋ ์ (p2)๋ฅผ ํ์ธ๋ ์ ์ผ๋ก ํ๋จํ๊ณ  ์คํ์ ๋ฃ๋๋ค.
            if (ccw(p1, p2, p[i]) > 0) {
                v.push_back(p2);
                break;
            }
            // ccw๊ฐ ์๋๋ฉด p2๋ฅผ ์ถ๊ฐํ์ง ๋ง๊ณ  p2์ด์ ์ 2์ ๊ณผ ํ์ฌ p[i]์ ccw์ธ์ง ๋น๊ตํ๋ค. (์ฒ์์ผ๋ก ๋์๊ฐ๋ค)
        }
        // while๋ฌธ์ ํต๊ณผํ๋ค๋ฉด ์ ์ด ์ถ๊ฐ๊ฐ ๋ ๊ฒ์ด๋ฏ๋ก ํ์ฌ ํ์ํ๋ ๊ฐ์ฅ ๋ฐ๊นฅ์ชฝ ์ ๋ ๋ฃ์ด์ค๋ค.
        v.push_back(p[i]);
    }
    cout << v.size() <<  '\n';
}๋ณด๋ค ๊น๋ํ Convex Hull Code
#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
struct Point {
   ll x, y;
   Point(ll a, ll b) :x(a), y(b) {};
   Point() {};
   bool operator<(const Point &rhs) const {
      if (x != rhs.x) return x < rhs.x;
      return y < rhs.y;
   }
};
vector<Point> point;
 
ll ccw(Point pt1, Point pt2, Point pt3) {
   ll ret = pt1.x*pt2.y + pt2.x*pt3.y + pt3.x*pt1.y;
   ret -= (pt2.x*pt1.y + pt3.x*pt2.y + pt1.x*pt3.y);
   return ret;
}
ll dist(Point pt1, Point pt2) {
   ll dx = pt2.x - pt1.x;
   ll dy = pt2.y - pt1.y;
   return dx * dx + dy * dy;
}
 
int main(){
    int N;
    cin >> N;
    point.resize(N);
    for (int i = 0; i < N; i++) {
        cin >> point[i].x >> point[i].y;
    }
    vector<Point> hull;
    swap(point[0], *min_element(point.begin(), point.end()));
    sort(point.begin() + 1, point.end(), [](Point x, Point y) {
       ll cw = ccw(point[0], x, y);
       if (cw == 0) return dist(point[0], x) < dist(point[0], y);
       return cw > 0;
    });
 
    for (auto i : point) {
        // hull์ ๋ค์์ 2๋ฒ์งธ ๊ฐ, 1๋ฒ์งธ ๊ฐ, ๊ทธ๋ฆฌ๊ณ  point์ 3๋ฒ์งธ ๊ฐ์ ๋น๊ตํ์ฌ
        // ๋ฐ์๊ณ๊ฐ ์๋๋ฉด hull์ ๋งจ ๋ค์ ์ ์ ๋บ๋ค.
        // ๋ฐ์๊ณ์ด๋ฉด ํด๋น ์ ์ ํฌํจํ ์ํ๋ก ๋ค์์ ์ ๋น๊ตํ๋ค.
       while (hull.size() >= 2 && ccw(hull[hull.size() - 2], hull.back(), i) <= 0) {
          hull.pop_back();
       }
       hull.push_back(i);
    }
    cout << hull.size() << endl;
}