티스토리 뷰

1. 문제

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

 

2. 코드

  • Problem의 정렬 조건 
    • 1. 난이도가 낮은 순으로 정렬한다.
    • 2. 난이도가 같다면 문제 번호가 낮은 순으로 정렬한다.
  • TreeSet을 사용하여 Problem 저장 시에 정렬이 될 수 있도록 한다.
  • TreeSet은 first(), last()를 사용하여 첫 번째 요소와 마지막 요소에 접근할 수 있다. (양방향 접근)
public class Main {

    static int N, M;
    static TreeSet<Problem> set = new TreeSet<>();
    static Map<Integer, Problem> map = new HashMap<>(); // {문제 번호, 문제}

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(br.readLine());
        for (int i = 0; i < N; i++) {
            String[] inputs = br.readLine().split(" ");
            int problemNumber = Integer.parseInt(inputs[0]); // 문제 번호
            int problemDifficulty = Integer.parseInt(inputs[1]); // 문제 난이도
            Problem problem = new Problem(problemNumber, problemDifficulty);
            set.add(problem);
            map.put(problemNumber, problem);
        }

        StringBuilder sb = new StringBuilder();
        M = Integer.parseInt(br.readLine());
        for (int i = 0; i < M; i++) {
            String[] inputs = br.readLine().split(" ");
            if (inputs.length == 3) { // add
                int problemNumber = Integer.parseInt(inputs[1]);
                int problemDifficulty = Integer.parseInt(inputs[2]);
                Problem problem = new Problem(problemNumber, problemDifficulty);
                set.add(problem);
                map.put(problemNumber, problem);
            } else {
                if ("solved".equals(inputs[0])) { // solved
                    int problemNumber = Integer.parseInt(inputs[1]);
                    Problem removedProblem = map.remove(problemNumber);
                    set.remove(removedProblem);
                } else { // recommend
                    int x = Integer.parseInt(inputs[1]);
                    // TreeSet을 사용하면 양방향으로 접근 가능
                    if (x == 1) { // 가장 어려운 문제 번호 출력
                        Problem problem = set.last(); // TreeSet#last() : 마지막 요소 접근
                        sb.append(problem.number + "\n");
                    } else { // 가장 쉬운 문제 번호 출력
                        Problem problem = set.first(); // TreeSet#first() : 첫번째 요소 접근
                        sb.append(problem.number + "\n");
                    }
                }
            }
        }

        System.out.println(sb);
    }

    static class Problem implements Comparable<Problem> {
        int number; // 문제 번호
        int difficulty; // 난이도

        public Problem(int number, int difficulty) {
            this.number = number;
            this.difficulty = difficulty;
        }

        @Override
        public int compareTo(Problem problem) {
            if (this.difficulty == problem.difficulty) {
                return this.number - problem.number;
            }
            return this.difficulty - problem.difficulty;
        }
    }
}

 

3. 새로 알게된 점

  • TreeSet을 사용하면 first()와 last()를 사용하여 양방향 접근이 가능하다는 것
    • first(), last() 시간 복잡도 : O(1)
    • TreeSet은 요소를 삽입할 때 트리를 자동으로 정렬하므로, 가장 작은 요소와 가장 큰 요소를 트리의 최좌단과 최우단에 미리 참조하고 있다.
    • 따라서 first()와 last()는 추가적인 탐색이나 연산 없이, 단순히 참조 값을 반환하므로 시간 복잡도는 O(1)이다.
Total
Today
Yesterday
최근에 올라온 글
«   2024/11   »
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