본문 바로가기

Algorithm

BOJ 10816번 숫자 카드 2

www.acmicpc.net/problem/10816

 

10816번: 숫자 카드 2

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

www.acmicpc.net

접근

1. 일반적인 이분탐색으로 접근 - 시간초과
2. 해시맵을 사용하여 접근 - 통과 
3. 이분탐색 중 상/하한선 (lower bound, upper bound) 발견 !

 

이론보기

jackpot53.tistory.com/33

 

이진탐색-상/하한선((lower bound,upper bound)

주어진 자료에서 중복되지 않은 값이 주어질 때 그 데이터내에 특정 값이 존재하는지 검색하는 방법 중  이진탐색(Binary Search)은 자료를 정렬한후 분할정복방식으로 데이터를 2/1씩 나누면서 값

jackpot53.tistory.com

 

풀이|

해시맵 (HashMAp)


1. 입력받은 수를 해시 맵에 저장
2. 기본값을 0으로 받아오고 1을 더해서 다시 저장
3. target 숫자들을 key로 value값 구해서 출력
 

상/하한선 (lower bound, upper bound)


1. 숫자들을 입력받는다.
2. target 숫자들의 lower bound, upper bound를 구한다.
3. upper bound - lower bound 값을 출력한다.
4. 값이 없는 경우엔 같은 값을 가르키므로 0이 출력됨.
5. 답이 있을 경우엔 답보다 큰값의 인덱스가 upper bound 이고  
답이 처음 나온곳이 lowwer bound 이므로 답의 갯수가 출력됨.

 

 

HashMap 사용 코드

import java.io.*;
import java.util.*;

class Main {
    static int stoi(String s) {
        return Integer.parseInt(s);
    }

    static int N;
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        N = stoi(br.readLine());
        st = new StringTokenizer(br.readLine());
        HashMap< Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < N; i++) {
            int temp = stoi(st.nextToken());
            Integer orDefault = map.getOrDefault(temp, 0);
            map.put(temp, orDefault+1);
        }

        int M = stoi(br.readLine());
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < M; i++) {
            int target = stoi(st.nextToken());
            System.out.print(map.getOrDefault(target,0) + " ");
        }
    }
}

 

 

이분탐색 lower bound / upper bound 사용 코드

 

import java.io.*;
import java.util.*;

class Main {
    static int stoi(String s) {
        return Integer.parseInt(s);
    }

    static int[] card;
    static int N;
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        N = stoi(br.readLine());
        card = new int[N];
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < N; i++) {
            card[i] = stoi(st.nextToken());
        }

        Arrays.sort(card);
        int M = stoi(br.readLine());
        int[] target = new int[M];
        st = new StringTokenizer(br.readLine());
        
        for (int i = 0; i < M; i++) {
            target[i] = stoi(st.nextToken());
        }

        for (int i : target) {
            int low = getLowerBound(i);
            int high = getUpperBound(i);
            System.out.print(high-low + " ");
        }
    }

    static int getLowerBound(int target){
        int left = 0;
        int right = N;

        while(left < right){
            int mid = (left + right)/2;
            if(card[mid] >= target){
                right = mid;
            } else {
                left = mid+1;
            }
        }

        return left;
    }

    static int getUpperBound(int target){
        int left = 0;
        int right = N;

        while(left < right){
            int mid = (left + right)/2;
            if(card[mid] <= target){
                left = mid+1;
            } else {
                right = mid;
            }
        }

        return left;
    }
}

'Algorithm' 카테고리의 다른 글

BOJ 7562 나이트의 이동  (0) 2020.06.23
BOJ 9237번 이장님 초대  (0) 2020.06.23
BOJ 1654번 랜선 자르기  (0) 2020.06.23
BOJ 1439번 뒤집기  (0) 2020.06.23
BOJ 15649번 N과 M (1)  (0) 2020.06.23