[BOJ] 10816번 숫자 카드 2 - C++

"이분탐색"

Posted by Yongmin on June 28, 2021

문제

숫자 카드 2

풀이

이분탐색을 통해서 시간 초과를 피해야 하는 문제이다. 해당코드는 Referece에서 가지고 왔다. lower_bound(해당 숫자가 맨 처음 나타나는 index)와 upper_bound(해당 숫자가 맨 나중에 나타나는 index)를 구해서 서로 빼주면 되는 문제이다. lower_bound와 upper_bound의 구현을 기억해두면 좋을 것 같다. 추가로, 일반적으로 이분탐색을 통해서 해당 숫자를 찾아내는(중복 숫자가 없을 때 유효) 코드도 첨부한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int BSearch(int arr[], int target) {
    int low = 0;
    int high = arr.length - 1;
    int mid;

    while(low <= high) {
        mid = (low + high) / 2;

        if (arr[mid] == target)
            return mid;
        else if (arr[mid] > target)
            high = mid - 1;
        else
            low = mid + 1;
    }
    return -1;
}

소스 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
#include <algorithm>

using namespace std;

int N, M;
int cards[500000];

int lowerBound(int n)
{
    int f = 0, l = N - 1, m;
    for (;;)
    {
        m = (f + l) / 2;

        if (f > l)
        {
            if (cards[f] == n) return f;
            else return -1;
        }

        if (cards[m] >= n) l = m - 1;
        else f = m + 1;
    }
}
/*
 10
 -10 -10 2 3 3 6 7 10 10 10
 8
 10 9 -5 2 3 4 5 -10
 */

int upperBound(int n)
{
    int f = 0, l = N - 1, m;
    for (;;)
    {
        m = (f + l) / 2;

        if (f > l)
        {
            if (cards[l] == n) return l;
            else return -1;
        }

        if (cards[m] <= n) f = m + 1;
        else l = m - 1;
    }
}

int main(void)
{
    cin.tie(NULL);
    ios::sync_with_stdio(false);

    cin >> N;
    for (int i = 0; i < N; i++)
        cin >> cards[i];
    sort(cards, cards + N);

    cin >> M;
    int n, res;
    for (int i = 0; i < M; i++)
    {
        cin >> n;
        res = upperBound(n);
        if (res == -1) cout << "0 ";
        else cout << res - lowerBound(n) + 1 << " ";
    }

    return 0;
}


# # #