Java - 알고리즘

백준 - 10825 국영수

TerianP 2022. 8. 18.
728x90

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

 

10825번: 국영수

첫째 줄에 도현이네 반의 학생의 수 N (1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 한 줄에 하나씩 각 학생의 이름, 국어, 영어, 수학 점수가 공백으로 구분해 주어진다. 점수는 1보다 크거나 같고, 1

www.acmicpc.net

 

문제

도현이네 반 학생 N명의 이름과 국어, 영어, 수학 점수가 주어진다. 이때, 다음과 같은 조건으로 학생의 성적을 정렬하는 프로그램을 작성하시오.

  1. 국어 점수가 감소하는 순서로
  2. 국어 점수가 같으면 영어 점수가 증가하는 순서로
  3. 국어 점수와 영어 점수가 같으면 수학 점수가 감소하는 순서로
  4. 모든 점수가 같으면 이름이 사전 순으로 증가하는 순서로 (단, 아스키 코드에서 대문자는 소문자보다 작으므로 사전순으로 앞에 온다.)

 

입력

첫째 줄에 도현이네 반의 학생의 수 N (1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 한 줄에 하나씩 각 학생의 이름, 국어, 영어, 수학 점수가 공백으로 구분해 주어진다. 점수는 1보다 크거나 같고, 100보다 작거나 같은 자연수이다. 이름은 알파벳 대소문자로 이루어진 문자열이고, 길이는 10자리를 넘지 않는다.

 

출력

문제에 나와있는 정렬 기준으로 정렬한 후 첫째 줄부터 N개의 줄에 걸쳐 각 학생의 이름을 출력한다.


풀이 방법

다시 한 번 Comparable 를 기억해보자!

=> comparable 사용시, 앞-뒤 계산 후 결과 값이 양수면 오름차순정렬, 음수면 내림차순정렬 !

이것만 기억하면 사실 이 문제는 보자마자 풀리는 수준의 문제이다.

그마나 조금 주의해야할 점은 이름을 비교하는 부분이다. 모든 점수가 같을 때 이름은 증가하는 순 즉 오름차순으로 처리해야한다. 

그런데 당연하게도 String 으로 받아온 name 을 단순히 - 연산 할 수 없다. 때문에 이 부분을 비교할 때는 name 에 대해서 다시 compareTo 메서드를 사용해서 int 값이 return 되도록 만들면 된다. 사실 코드는 정말 문제를 보자마자 바로 짰는데 딱 이부분에서 막혀서 String을 다시 char 로 만들어서 비교하고 어쩌고하다가 compareTo 안에서 다시 String 에 대해서 compareTo 를 사용하면 바로 풀린다는 것을 알았다.

개인적으로 이렇게 compareTo 안에서 String 으로 다시 compareTo 로 비교할 수 있다는 점이 신기했고, 또 배워간다는 생각을 했던 문제였다.

 

나머지는 주석 참고!

package baekJoon;

import java.io.*;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class Quiz_10825 {
    static PriorityQueue<Score> q = new PriorityQueue<Score>();

    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++){
            StringTokenizer st = new StringTokenizer(br.readLine(), " ");
            String name = st.nextToken();
            int kor = Integer.parseInt(st.nextToken());
            int eng = Integer.parseInt(st.nextToken());
            int math = Integer.parseInt(st.nextToken());

            q.offer(new Score(name, kor, eng, math));
        }

        while (!q.isEmpty()) {
//            sb.append(q.poll().name+"\n");
            bw.write(q.poll().name + "\n");
        }
        bw.flush();
    }
}

class Score implements Comparable<Score> {
    String name;
    int kor;
    int eng;
    int math;

    Score(String name, int kor, int eng, int math) {
        this.name = name;
        this.kor = kor;
        this.eng = eng;
        this.math = math;
    }


    @Override
    public int compareTo(Score o) {
        // 국어 점수가 다르다면 감소하는 순 -> 내림차순
        if (this.kor != o.kor) {
            return o.kor - this.kor;
        }else{
            // 국어 점수는 같고, 영어점수가 다르다면 -> 영어점수는 증가하는순 -> 오름차순
            if (this.eng != o.eng) {
                return this.eng - o.eng;
            }else{
                // 국어점수, 영어점수가 같고, 수학점수가 다르다면 -> 수학점수는 감소하는 순 -> 내림차순
                if (this.math != o.math) {
                    return o.math - this.math;
                }else{
                    // 모든 점수가 같다면 이름을 증가하는 순 -> 오름차순
                    return this.name.compareTo(o.name);
                }
            }
        }
    }
}

 

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

백준 - 3055 탈출  (0) 2022.08.19
백준 - 20291 파일 정리  (0) 2022.08.19
백준 - 7568 덩치  (0) 2022.08.18
백준 - 14226 이모티콘  (0) 2022.08.15
백준 - 13549 숨바꼭질3  (0) 2022.08.13

댓글