반응형
12-24 00:25
Today
Total
«   2024/12   »
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
관리 메뉴

개발하는 고라니

[백준] 10816번 : 숫자 카드 2 본문

Programming/백준

[백준] 10816번 : 숫자 카드 2

조용한고라니 2021. 3. 13. 01:43
반응형
 

10816번: 숫자 카드 2

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

www.acmicpc.net


[해싱 + 이진 탐색 (Hashing + Binary Search)]

해싱없이 이진 탐색만으로 값을 검색하면 온전히 모든 값을 다 돌지 못한다. 예를 들어 10이 몇 개 있는지 검색을 할 때 10이 3개 있다고 가정한다면 3개를 모두 돌지 못할 수 있다.

 

따라서 해싱을 이용해 배열에 해당 값이 몇 개가 있는지 저장해놓으면 편리하다. 나는 다음과 같은 해싱을 사용하였다. 값의 범위는 (-10,000,000 ~ 10,000,000)이므로 2천만개의 공간이 필요하다.

    static int hashing(int x){
        if(x < 0) return x * (-1) + 10000000;
        return x;
    }

값이 있는지 검색의 결과는 flag에 저장해 값이 있음/없음을 판별해 출력하도록 하였고, StringBuilder를 사용하여 시간을 줄였다.

# Code </>

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

public class Main {

    static int hashing(int x){
        if(x < 0) return x * (-1) + 10000000;
        return x;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        List<Integer> list = new ArrayList<>();
        int n = Integer.parseInt(br.readLine());
        int[] num = new int[n], result = new int[20000001];

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

            result[hashing(num[i])]++;
        }

        Arrays.sort(num);
        int m = Integer.parseInt(br.readLine());

        StringBuilder sb = new StringBuilder();
        st = new StringTokenizer(br.readLine());
        for(int i=0; i<m; i++) {

            int target = Integer.parseInt(st.nextToken());
            int left = 0, right = n-1;
            boolean flag = false;

            while (left <= right) {

                int mid = (left + right) / 2;

                if (num[mid] == target) {
                    flag = true;
                    break;
                }

                if (num[mid] > target)
                    right = mid - 1;
                else
                    left = mid + 1;
            }
            sb.append(flag? result[hashing(target)] + " " : "0 ");
        }
        System.out.println(sb.toString());
    }
}
반응형

'Programming > 백준' 카테고리의 다른 글

[백준] 1058번 : 친구  (0) 2021.03.14
[백준] 9019번 : DSLR  (0) 2021.03.13
[백준] 1654번 : 랜선 자르기  (0) 2021.03.13
[백준] 10815번 : 숫자 카드  (0) 2021.03.12
[백준] 1963번 : 소수 경로  (0) 2021.03.12
Comments