Java - 알고리즘

백준 - 11652 카드

TerianP 2022. 8. 20.
728x90

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

 

11652번: 카드

준규는 숫자 카드 N장을 가지고 있다. 숫자 카드에는 정수가 하나 적혀있는데, 적혀있는 수는 -262보다 크거나 같고, 262보다 작거나 같다. 준규가 가지고 있는 카드가 주어졌을 때, 가장 많이 가지

www.acmicpc.net

 

문제

준규는 숫자 카드 N장을 가지고 있다. 숫자 카드에는 정수가 하나 적혀있는데, 적혀있는 수는 -2^62보다 크거나 같고, 2^62보다 작거나 같다.

준규가 가지고 있는 카드가 주어졌을 때, 가장 많이 가지고 있는 정수를 구하는 프로그램을 작성하시오. 만약, 가장 많이 가지고 있는 정수가 여러 가지라면, 작은 것을 출력한다.

 

입력

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

 

출력

첫째 줄에 준규가 가장 많이 가지고 있는 정수를 출력한다.


풀이방법

어제 탈출 보다 훨~~씬 쉬운 문제.

나의 자존감 회복과 휴식을 위해서 쉬운 문제를 골랐다. 이 문제에서 가장 주의해야하는 점은 아래와 같다.

 

1. 숫자의 범위에 주의하자. 일반적인 int 형으로 잡으면 -2^62 ~ 2^62 임으로 범위를 벗어나서 틀렸다고 나온다.

 

2. 조건에 주의하자. 가장 많은 카드가 있을 때 가장 높은 수를 출력하는 것이 아니라, 가장 많은 카드의 가장 낮은 숫자를 출력하는 것이다.

 

3. 머리쓴다고 ComparableTo 를 쓰지는 말자

처음에 나름 머리쓴다고 ComparableTo 를 사용해서 2번 조건에 만족하도록 sort 후 가장 앞에 있는 값을 가져오는 방법으로 풀었는데ㅠㅠ 이상하게 틀렸다고 나오더라ㅠㅠ

ComparableTo 는 int 를 return 하는데 나는 숫자의 범위 때문에 long 을 받아야한다. 즉 결국 비교를 위해서 this.long - o.long 를 연산한 후 해당값을 int 로 형변환 후 return 하게 되는데 여기서 로직상 문제가 발생하는 것 같았다.

정확히는 long - long 을 한 값을 int 로 형변환 하는 과정에서 숫자 오버플로우? 가 발생하게 되고, 정확하지 않은 int 값이 나와서 에러가 나는게 아닐까...하고 생각이 된다.

 

물론 내가 코드를 잘못짜서 그런걸거고, 로직만 잘 세우면 ComparableTo 로도 풀릴거라고 생각된다.

 

나머지는 주석 참고!

package baekJoon;

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

public class Quiz_11652 {
    // 카드의 숫자와 갯수를 저장하기 위한 map
    static HashMap<Long, Integer> map = new HashMap<Long, Integer>();

    // 최종 결과를 저장하기 위한 result
    static long result = 0;

    // 최대값을 저장하기 위한 max
    static int max = Integer.MIN_VALUE;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        int n = Integer.parseInt(br.readLine());

        for (int i = 0; i < n; i++) {
            long d = Long.parseLong(br.readLine());
            // 하나의 카드를 입력받을 때마다 map.getOrDefault 메서드를 실행해서 해당 값이 있으면 해당 값을 가져오고, 아니면 0 을 가져온다
            // 그리고 +1 => 이를 통해서 map 에 없었던 카드는 1 로 들어가고 있었던 카드는 기존값+1
            map.put(d, map.getOrDefault(d, 0) + 1);
        }

        // map 의 forEach 메서드 : 람다식을 사용해서 구현한다.
        // 일종의 향상된 for 문으로 생각하면 될듯?
        // 여기서 l 은 key, i 는 value 를 의미한다.
        map.forEach((l, i) -> {

            // 현재 max 가 i 보다 작으면 => 즉 현재 value 가 max 보다 크다면
            if (max < i) {
                // result 에 현재 l(key)을 저장하고
               result = l;
               // max 에 현재 i 를 저장한다.
               max = i;
            } else if (max == i) {
                // 만약 현재 max 와 i 가 일치한다면
                // result 에는 더 작은 값을 비교해서 넣는다.
                result = Math.min(result, l);
            }
        });

        // 그리고 출력하면 끝!!
        bw.write(result + "\n");
        bw.flush();

    }
}

 

처참한 전투의 흔적ㅠ

'Java - 알고리즘' 카테고리의 다른 글

백준 - 5397 키로거  (0) 2022.08.22
백준 - 2798 블랙잭  (0) 2022.08.21
백준 - 3055 탈출  (0) 2022.08.19
백준 - 20291 파일 정리  (0) 2022.08.19
백준 - 10825 국영수  (0) 2022.08.18

댓글