본문 바로가기
PS/BOJ

[자바] 백준 1205 - 등수 구하기 (java)

by Nahwasa 2023. 4. 5.

문제 : boj1205

 

 

필요 알고리즘

  • 구현
    • 결국 문제에서 제시된 방식대로 등수를 구해주면 되는 구현문제이다. 다만 실수하가기가 쉽게 문제가 구성되어 있다.

※ 제 코드에서 왜 main 함수에 로직을 직접 작성하지 않았는지, 왜 Scanner를 쓰지 않고 BufferedReader를 사용했는지 등에 대해서는 '자바로 백준 풀 때의 팁 및 주의점' 글을 참고해주세요. 백준을 자바로 풀어보려고 시작하시는 분이나, 백준에서 자바로 풀 때의 팁을 원하시는 분들도 보시는걸 추천드립니다.

 

 

풀이

  예외를 잘 처리해줘야 하는 구현 문제이다. 차분하게 조건들 다 따져가면서 구현해주면 된다.

 

1. n = 0일 경우 답은 항상 1이다. (P의 최소값은 10 이므로 불가능한 경우가 없다.)

if (n == 0) {
    System.out.println(1);
    return;
}

 

 

2. 이제 입력받으면서 새로운 점수(이하 score) 가 어디 들어가야할지 찾는다.

st = new StringTokenizer(br.readLine());
int rank = -1;	// 태수의 등수
int bf = -1;	// 이전 값
int bfIdx = -1;	// 이전 값이 시작한 인덱스 '5 5 5 4'에서 '4'를 보고있다면 bf는 5, bfIdx는 1이다. 인덱스가 곧 등수다. 
for (int i = 1; rank == -1 && i <= n; i++) {
    int cur = Integer.parseInt(st.nextToken());
    if (cur < score) {	// 태수의 새로운 점수보다 현재 보고 있는 점수가 낮다면 거기 들어가야한다.
        rank = bf == score ? bfIdx : i;	// 이전값이 score와 같다면 이전값의 맨 처음값(bfIdx)
    }
    if (bf != cur) {	// bf와 현재 값이 다르다면 바꿔줘야한다.
        bf = cur;
        bfIdx = i;
    }

}

 

 

3. rank가 -1인 경우는, score보다 작은 값이 입력중에 없었으므로 가장 마지막에 붙여야 하는 경우이다. 그 경우 입력값이 모두 동일했다면 (score == bf인 경우) '1'이 답이 될 것이고, 그렇지 않다면 n+1이 답이 될 것이다. 다만 n+1이 p를 초과한다면 -1이 답이 된다. 그걸 처리한 부분이다.

if (rank == -1 && n+1 <= p)
    rank = score == bf ? bfIdx : n+1;

 

4. rank가 -1이 아니었던 경우 최종적으로 rank가 p 이하인지 확인해서 출력해준다. '3'을 거친 경우 무조건 rank는 p 이하이다.

System.out.println(rank <= p ? rank : -1);

 

 

코드 : github

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    public static void main(String[] args) throws Exception {
        new Main().solution();
    }

    private void solution() throws Exception {
        StringTokenizer st = new StringTokenizer(br.readLine());
        int n = Integer.parseInt(st.nextToken());
        int score = Integer.parseInt(st.nextToken());
        int p = Integer.parseInt(st.nextToken());

        if (n == 0) {
            System.out.println(1);
            return;
        }

        st = new StringTokenizer(br.readLine());
        int rank = -1;
        int bf = -1;
        int bfIdx = -1;
        for (int i = 1; rank == -1 && i <= n; i++) {
            int cur = Integer.parseInt(st.nextToken());
            if (cur < score) {
                rank = bf == score ? bfIdx : i;
            }
            if (bf != cur) {
                bf = cur;
                bfIdx = i;
            }

        }

        if (rank == -1 && n+1 <= p)
            rank = score == bf ? bfIdx : n+1;

        System.out.println(rank <= p ? rank : -1);
    }
}