[ 백준 ] 3020 / 개똥벌레

金弘均·2021년 9월 16일
0

Baekjoon Online Judge

목록 보기
188/228
post-thumbnail
post-custom-banner

# Appreciation

/*
 * Problem :: 3020 / 개똥벌레
 *
 * Kind :: Binary Search
 *
 * Insight
 * - 일단 석순은 석순끼리, 종유석은 종유석끼리 나누자
 *   + 석순 기준 1번째 구간으로 개똥벌레가 날아가면,
 *     크기 1 이상인 석순은 모두 파괴된다
 *     석순 기준 2번째 구간으로 개똥벌레가 날아가면,
 *     크기 2 이상인 석순은 모두 파괴된다
 *     # 파괴되는 석순을 일일이 세면... O(NH) > O(10^8) 이라서 제한시간 내에 풀 수 없다
 *       크기 n 이상의 석순의 개수를 빨리 알 수 있는 방법은 없을까?
 *       -> 오름차순으로 정렬해놓고 lower_bound 쓰면
 *          첫번째로 만나는 크기 n 이상인 석순의 위치를 찾을 수 있다! <- log(N)
 *          Vector 라면 end - lower_bound 로 쉽게 크기 n 이상의 석순의 개수를 알 수 있다!
 *
 * Point
 * - 종유석은 거꾸로 매달려 있으므로
 *   + 종유석 기준 1번째 구간으로 개똥벌레가 날아가면,
 *     크기 H 이상인 종유석은 모두 파괴된다
 *     종유석 기준 2번째 구간으로 개똥벌레가 날아가면,
 *     크기 H-1 이상인 종유석은 모두 파괴된다
 *     # 오름차순으로 정렬해놓고 lower_bound 쓰는 것은 같되
 *       i번째 구간으로 개똥벌레가 날아가면
 *       크기 H-i+1 이상인 종유석이 파괴되는 것을 염두에 두자
 */

# Code

//
//  BOJ
//  ver.C++
//
//  Created by GGlifer
//
//  Open Source

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

#define endl '\n'

// Set up : Global Variables
/* None */

// Set up : Functions Declaration
/* None */


int main()
{
    // Set up : I/O
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    // Set up : Input
    int N, H;
    cin >> N >> H;
    vector<int> U(N/2), D(N/2); /* 차례로 석순의 크기와 종유석의 크기를 저장하는 Vector */
    for (int i=0; i<N/2; i++)
        cin >> U[i] >> D[i];

    // Process
    sort(U.begin(), U.end()); /* 오름차순으로 석순 정렬 */
    sort(D.begin(), D.end()); /* 오름차순으로 종유석 정렬 */

    int ans1 = -1, ans2 = 0; /* ans1 = 파괴해야 하는 장애물의 최솟값,
                              * ans2 = 그러한 구간의 수 */
    for (int h=1; h<=H; h++) {
        /* 높이 h 일 때 */
        /* 파괴되는 석순의 개수 */
        int u_cnt = U.end() - lower_bound(U.begin(), U.end(), h);
        /* 파괴되는 종유석의 개수 */
        int d_cnt = D.end() - lower_bound(D.begin(), D.end(), H-h+1);
        int cnt = u_cnt + d_cnt; /* 총 파괴되는 장애물의 개수 */
        if (ans1 == -1 || ans1 > cnt) {
            ans1 = cnt;
            ans2 = 1;
        } else if (ans1 == cnt) {
            ans2++;
        }
    }

    // Control : Output
    cout << ans1 << ' ' << ans2 << endl;
}

// Helper Functions
/* None */
profile
이런 미친 게임을 봤나! - 옥냥이
post-custom-banner

0개의 댓글