μƒˆμ†Œμ‹

μ•Œκ³ λ¦¬μ¦˜/BaekJoon

[C++] BOJ 2244번: λ―Όμ½”μš°μŠ€ν‚€ ν•©

  • -
728x90

문제

두 λ‹€κ°ν˜•μ΄ μ£Όμ–΄μ‘Œμ„ λ•Œ, 두 λ‹€κ°ν˜•μ˜ λ―Όμ½”ν”„μŠ€ν‚€ 합을 κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€. λ§Œμ•½ λ―Όμ½”ν”„μŠ€ν‚€ 합이 μ—¬λŸ¬ 개의 λ‹€κ°ν˜•μœΌλ‘œ 이루어진닀면 λ‹€μŒμ˜ μš°μ„ μˆœμœ„μ— 따라 ν•˜λ‚˜μ˜ λ‹€κ°ν˜•λ§Œμ„ κ΅¬ν•˜λ„λ‘ ν•œλ‹€. λ²ˆν˜Έκ°€ μž‘μ€ 것이 μš°μ„ μˆœμœ„κ°€ 높은 것이닀.

 

μž…λ ₯ 1

3 3
0 0
1 0
1 1
0 1
0 0
1 0

좜λ ₯ 1

5
0 0
2 0
2 1
1 2
0 1

μ½”λ“œ

#include<iostream>
#include<algorithm>
#include<vector>
#define x first
#define y second
using namespace std;

//2244번 λ―Όμ½”ν”„μŠ€ν‚€ ν•©
//Convex Hull(CCW(Counter Clock Wise)) μ‚¬μš©

typedef pair<long long, long long> Point2f;
Point2f a[1010];
Point2f b[1010];

//counter clock wise : μ’ŒνšŒμ „ν•˜λŠ”μ§€ νŒλ‹¨
//벑터 AB와 벑터 AC의 CW/CCW
// 0보닀 크면 λ°˜μ‹œκ³„λ°©ν–₯으둜 λ„λŠ” 것, 0보닀 μž‘μœΌλ©΄ μ‹œκ³„λ°©ν–₯으둜 λ„λŠ” 것
//int에 1LL을 κ³±ν•΄μ£Όλ©΄ long long으둜 ν˜•λ³€ν™˜μ„ μ‰½κ²Œ ν•  수 있음
int ccw(Point2f a, Point2f b, Point2f c) {
    long long res = a.x * b.y + b.x * c.y + c.x * a.y;
    res -= b.x * a.y + c.x * b.y + a.x * c.y;
    if (res > 0) return 1;          //μ‹œκ³„ λ°˜λŒ€λ°©ν–₯
    if (res) return -1;             //μ‹œκ³„ λ°©ν–₯
    return 0;                           //평면상
}

long long dist(Point2f a, Point2f b) {
    long long dx = 1LL*a.x - b.x;
    long long dy = 1LL * a.y - b.y;
    return dx * dx + dy * dy;
}

int main() {

    vector<Point2f> arr;
    int aNum, bNum;
    int xTmp, yTmp;
    int pIdx = 0;
    cin >> aNum >> bNum;
    pIdx = aNum * bNum;
    for (int i = 0; i < aNum; i++) {
        cin >> xTmp >> yTmp;
        a[i].x = xTmp; a[i].y = yTmp;
    }
    for (int i = 0; i < bNum; i++) {
        cin >> xTmp >> yTmp;
        b[i].x = xTmp; b[i].y = yTmp;
    }
    //λͺ¨λ“  κ°€λŠ₯성이 μžˆλŠ” 점듀 vector μ œμž‘
    for (int i = 0; i < aNum; i++) {
        for (int j = 0; j < bNum; j++) {
            arr.push_back(Point2f{ a[i].x + b[j].x,a[i].y + b[j].y });
        }
    }

    //arr의 μ΅œμ†Œ 값을 μ°Ύμ•„μ„œ 0번 μžλ¦¬μ™€ λ°”κΏˆ(0λ²ˆμ„ 제일 μž‘μ€ κ°’μœΌλ‘œ μ„€μ •)
    swap(arr[0], *min_element(arr.begin(), arr.end()));
    //0λ²ˆμ„ μ œμ™Έν•œ 점듀을 λ°˜μ‹œκ³„ λ°©ν–₯으둜 μ •λ ¬
    //[&]{}λŠ” λžŒλ‹€μ‹μœΌλ‘œμ¨ ν•΄λ‹Ή ν•¨μˆ˜μ—λ”°λΌμ„œ sortλ₯Ό 할지 말지 결정함
    sort(arr.begin() + 1, arr.end(), [&](Point2f& a, Point2f& b) {
        int cw = ccw(arr[0], a, b);
        //cwκ°€ 0 이상이면 λ°˜μ‹œκ³„ λ°©ν–₯이고 trueλ₯Ό λ°˜ν™˜ 0이면 false λ°˜ν™˜, cwκ°€ -1인 경우(μ‹œκ³„ λ°©ν–₯) if문을 λ“€μ–΄μ˜€μ§€ μ•ŠμŒ
        if (cw) return cw > 0;          
        return dist(arr[0], a) < dist(arr[0], b); //cwκ°€ -1인 경우 기쀀점 arr[0]μ—μ„œμ˜ 거리순으둜 μ •λ ¬
        });

    vector<Point2f> hull;
    for (int i = 0; i < arr.size();i++) {
        while (hull.size() >= 2 && ccw(hull[hull.size() - 2], hull.back(), arr[i]) <= 0) {
            hull.pop_back();
        }
        hull.push_back(arr[i]);
    }
    cout << hull.size() << "\n";
    for (int i = 0; i < hull.size(); i++) {
        cout << hull[i].x << " " << hull[i].y << "\n";
    }

    return 0;
}

 

*κ°„λ‹¨ν•œ ν•΄μ„€*

convex hull둜 κ΅¬ν˜„ν•˜λ©΄ λ˜λŠ” λ¬Έμ œμ΄λ‹€.

convex hull은 주어진 μ μ—μ„œ 외곽선을 μ΄λ£¨λŠ” 점듀을 μ°ΎλŠ” μ•Œκ³ λ¦¬μ¦˜μΈλ° λ―Όμ½”ν”„μŠ€ν‚€μ˜ ν•© λ˜ν•œ κ³΅κ°„μ˜ 합을 κ³„μ‚°ν•˜λŠ” 것이기 λ•Œλ¬Έμ— convex hull μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©ν•˜μ—¬ κ΅¬ν˜„ν•˜λ©΄ λœλ‹€.

μ½”λ“œμ˜ 핡심적인 뢀뢄은 https://justicehui.github.io/ioi/2019/05/21/BOJ2244/ μ—μ„œ λ”°μ™”λ‹€.

λͺ‡κ°€μ§€ λžŒλ‹€μ‹μ΄λΌλ˜μ§€ auto와 같은 것듀이 λ‚˜μ—κ²Œ μ–΄λ €μ›Œμ„œ for문으둜 λ°”κΎΈκ±°λ‚˜ 주석을 λ‹¬μ•„μ„œ μ§„ν–‰ν•΄λ³΄μ•˜λ‹€. 기쑴의 λ‹€λ₯Έκ³³μ—μ„œ μ°Ύμ•„μ„œ convex hull을 κ΅¬ν˜„ν•΄μ„œ λ„£μ–΄λ³΄μ•˜λŠ”λ° 예제λ₯Ό λ„£μ–΄λ³΄μ•˜μ„ λ•ŒλŠ” 좜λ ₯ κ²°κ³Όκ°€ μž˜λ‚˜μ™”μ—ˆλ‹€. ν•˜μ§€λ§Œ λ°±μ€€μ—μ„œ ν…ŒμŠ€νŠΈ ν• λ•Œλ§ˆλ‹€ 

μ΄λŸ¬ν•œ λŸ°νƒ€μž„ μ—λŸ¬λ‚˜ 좜λ ₯ μ΄ˆκ³Όκ°€ λ‚˜μ™€μ„œ 뭐가 λ¬Έμ œμΈμ§€ λͺ°λΌμ„œ λ‹€λ₯Έ λΆ„ λΈ”λ‘œκ·Έλ₯Ό 보고 μ°Έκ³ ν•΄μ„œ ν•΄λ³΄μ•˜λŠ”λ° μ•„λ§ˆ sortingν•˜λŠ” κ³Όμ •μ—μ„œ μ—λŸ¬κ°€ λ‚œκ²Œ μ•„λ‹κΉŒ μ‹Άλ‹€..

convex hull μ•Œκ³ λ¦¬μ¦˜μ— λŒ€ν•œ 글은 https://kbw1101.tistory.com/50 μ—¬κΈ° λΈ”λ‘œκ·Έμ— μ•„μ£Ό μΉœμ ˆν•˜κ²Œ μ„€λͺ…λ˜μ–΄ μžˆλ‹€.

 

 

 

*이 λ°©λ²•λ§Œμ΄ λ§žλŠ” 정닡은 μ•„λ‹™λ‹ˆλ‹€.

훨씬 μ’‹κ³  λΉ λ₯Έ λ‹€λ₯Έ μ•Œκ³ λ¦¬μ¦˜μ„ κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ•Œκ³ λ¦¬μ¦˜ κ³΅λΆ€ν•˜μ‹œλŠ” λΆ„λ“€ ν™”μ΄νŒ…! '0'/*

λ°˜μ‘ν˜•
Contents

ν¬μŠ€νŒ… μ£Όμ†Œλ₯Ό λ³΅μ‚¬ν–ˆμŠ΅λ‹ˆλ‹€

이 글이 도움이 λ˜μ—ˆλ‹€λ©΄ 곡감 λΆ€νƒλ“œλ¦½λ‹ˆλ‹€.