10816번: 숫자 카드 2

Joo·2022년 11월 18일

백준

목록 보기
59/113

https://www.acmicpc.net/problem/10816

문제

숫자 카드는 정수 하나가 적혀져 있는 카드이다. 상근이숫자 카드 N개를 가지고 있다. 정수 M개가 주어졌을 때, 이 수가 적혀있는 숫자 카드를 상근이가 몇 개 가지고 있는지 구하는 프로그램을 작성하시오.

입력

첫째 줄에 상근이가 가지고 있는 숫자 카드의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 둘째 줄에는 숫자 카드에 적혀있는 정수가 주어진다.

숫자 카드에 적혀있는 수는 -10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다.

셋째 줄에는 M(1 ≤ M ≤ 500,000)이 주어진다. 넷째 줄에는 상근이가 몇 개 가지고 있는 숫자 카드인지 구해야 할 M개의 정수가 주어지며, 이 수는 공백으로 구분되어져 있다.

이 수도 -10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다.

출력

첫째 줄에 입력으로 주어진 M개의 수에 대해서, 각 수가 적힌 숫자 카드를 상근이가 몇 개 가지고 있는지를 공백으로 구분해 출력한다.

예제 입력 1

10
6 3 2 10 10 10 -10 -10 7 3
8
10 9 -5 2 3 4 5 -10

예제 출력 1

3 0 0 1 2 0 0 2

풀이

  • 이분 탐색 - lowerBound & upperBound

업로드중..

package binary_search;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main_10816 {

    private static int numberOfCard;
    private static int numberOfFind;
    private static int[] cards;
    private static int[] findCards;
    private static StringBuilder sb = new StringBuilder();

    public static void main(String[] args) throws IOException {
        input();
        process();
        output();
    }

    private static void input() throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        numberOfCard = Integer.parseInt(br.readLine());
        cards = new int[numberOfCard];

        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < numberOfCard; i++) {
            cards[i] = Integer.parseInt(st.nextToken());
        }

        numberOfFind = Integer.parseInt(br.readLine());
        findCards = new int[numberOfFind];

        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < numberOfFind; i++) {
            findCards[i] = Integer.parseInt(st.nextToken());
        }
    }

    private static void process() {
        Arrays.sort(cards);

        for (int i = 0; i < numberOfFind; i++) {
            int findCard = findCards[i];
            int lowerBound = findLowerBound(0, numberOfCard - 1, findCard);
            int upperBound = findUpperBound(0, numberOfCard - 1, findCard);

            sb.append(upperBound - lowerBound + 1).append(" ");
        }
    }

    private static int findUpperBound(int start, int end, int findCard) {
        int result = -1;

        while (start <= end) {
            int mid = (start + end) / 2;
            int currentCard = cards[mid];

            if (currentCard <= findCard) {
                start = mid + 1;

                if (currentCard == findCard) {
                    result = mid;
                }
            } else {
                end = mid - 1;
            }
        }

        return result;
    }

    private static int findLowerBound(int start, int end, int findCard) {
        int result = 0;

        while (start <= end) {
            int mid = (start + end) / 2;
            int currentCard = cards[mid];

            if (currentCard >= findCard) {
                end = mid - 1;

                if (currentCard == findCard) {
                    result = mid;
                }
            } else {
                start = mid + 1;
            }
        }

        return result;
    }

    private static void output() {
        System.out.println(sb);
    }

}

0개의 댓글