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

2022. 6. 13. 20:29Β·μ•Œκ³ λ¦¬μ¦˜/BaekJoon
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'/*

λ°˜μ‘ν˜•

'μ•Œκ³ λ¦¬μ¦˜ > BaekJoon' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

[C++] BOJ 6087번: λ ˆμ΄μ € 톡신  (0) 2022.06.28
[C++] BOJ 2749번: ν”Όλ³΄λ‚˜μΉ˜ 수 3  (0) 2022.06.20
[C++] BOJ 2933번: λ―Έλ„€λž„  (0) 2022.06.13
[C++] BOJ 1655번: κ°€μš΄λ°λ₯Ό λ§ν•΄μš”  (1) 2022.06.08
[C++] BOJ 3190번: λ±€  (0) 2022.03.25
'μ•Œκ³ λ¦¬μ¦˜/BaekJoon' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€
  • [C++] BOJ 6087번: λ ˆμ΄μ € 톡신
  • [C++] BOJ 2749번: ν”Όλ³΄λ‚˜μΉ˜ 수 3
  • [C++] BOJ 2933번: λ―Έλ„€λž„
  • [C++] BOJ 1655번: κ°€μš΄λ°λ₯Ό λ§ν•΄μš”
KiTFOx
KiTFOx
  • KiTFOx
    KiTFOx's Notepad πŸ“
    KiTFOx
  • 곡지사항

    • πŸ“’ KiTFOx
  • 250x250
    • KiTFOx (118)
      • 곡뢀 (8)
        • CㆍC++ (7)
        • Design Pattern (2)
        • Crowd Simulation (2)
        • LearnOpenGL λ²ˆμ—­ (3)
        • OpenGL 자료 λ²ˆμ—­ (2)
        • OpenGL (1)
        • UE 자료 λ²ˆμ—­ (1)
        • AR (0)
        • OpenCV (0)
      • μ•Œκ³ λ¦¬μ¦˜ (50)
        • 자료ꡬ쑰 (3)
        • BaekJoon (35)
        • Programmers (11)
      • OpenGL 따라가기 (2)
      • κ²Œμž„μ—”μ§„ (15)
        • Unity (13)
        • UE4 (0)
        • UE5 (2)
      • λ©”νƒ€λ²„μŠ€ (4)
        • Engage VR (3)
        • Altspace VR (1)
      • 포트폴리였 ν”„λ‘œμ νŠΈ (2)
        • NewRo (1)
        • Amaimon(Unity3D) (0)
        • ArenaSurvival(UE5) (0)
      • κ°œλ°œμΌμ§€ (1)
        • Pub-Simulator (1)
        • Project-B (0)
      • λ„€νŠΈμ›Œν¬ (4)
      • Etc Study (5)
      • λŒ€μ™Έν™œλ™ (8)
        • ν¬λž˜ν”„ν†€ μ •κΈ€ κ²Œμž„λž© (6)
      • 회고둝 (0)
      • κ²Œμž„ ν•œκΈ€νŒ¨μΉ˜ (0)
  • hELLOΒ· Designed Byμ •μƒμš°.v4.10.3
KiTFOx
[C++] BOJ 2244번: λ―Όμ½”μš°μŠ€ν‚€ ν•©
μƒλ‹¨μœΌλ‘œ

ν‹°μŠ€ν† λ¦¬νˆ΄λ°”