1. 문제
현주는 N명의 인원이 참여하는 프로그래밍 스터디 그룹을 이끌고 있다.
현주는 스터디를 위해 대회를 세 개 개최하였고, 모든 구성원이 각 대회에 참여하였다. 참가자는 각 대회에서 0 이상 1,000 이하의 정수인 점수를 얻는다. 한 대회에서 둘 이상의 참가자가 동점이 나오는 경우도 있을 수 있다.
현주는 각 대회별 등수 및 최종 등수를 매기고 싶다. 등수는 가장 점수가 높은 사람부터 1등, 2등, ···, N등의 순서대로 붙는다. 만일 동점이 있을 경우 가능한 높은 (등수의 수가 작은) 등수를 부여한다. 즉, 점수가 내림차순으로 10,7,6,6,4의 순서일 경우, 6점을 받은 두 사람은 공동 3등이 되고, 그 다음 순서인 4점을 받은 사람은 5등이 된다. 이 규칙을 다르게 표현하면 다음과 같다: 각 사람마다 “나보다 점수가 큰 사람”의 수를 세어 1을 더한 것이 자신의 등수가 된다. 대회별 등수는 각 대회에서 얻은 점수를 기준으로 하며 최종 등수는 세 대회의 점수의 합을 기준으로 한다.
각 참가자의 대회별 등수 및 최종 등수를 출력하는 프로그램을 작성하시오.
2. 풀이
Score class
점수와 순서를 저장할 클래스를 하나 만든다. 나중에 sort에 사용하기 위해 comparable을 상속받은 뒤 compareTo를 오버라이딩했다.(내림차순)
static class Score implements Comparable<Score> {
int idx;
int score;
public Score(int idx, int score){
this.idx = idx;
this.score = score;
}
public int compareTo(Score o){
return o.score-this.score;
}
}
setOrder
등수가 담긴 배열을 반환하는 메서드다.
1. Score배열을 내림차순으로 정렬한다.
2. tmp배열을 만들어서 등수를 저장한다.
3. 1등을 미리 저장한 후 다음 인덱스부터 탐색한다. 만약 이전점수와 현재점수가 같지않다면 order에 현재인덱스+1을 해서 새로운 등수로 바꾼다.
4. tmp배열 current[j].idx자리에 order를 저장한다.
public static int[] setOrder(Score[] current){
Arrays.sort(current);
int[] tmp = new int[N];
int order = 1;
tmp[current[0].idx] = order;
for(int j=1;j<N;j++){
if(current[j-1].score != current[j].score){
order = j+1;
}
tmp[current[j].idx] = order;
}
return tmp;
}
Main
1. N을 입력받는다.
2. 답을 저장할 StringBuilder를 선언하고, 전체 총점을 저장할 total을 만들면서 각 배열요소 하나하나에 Score 객체를 미리 만들어둔다.
3. 세 번의 테스트마다 점수를 입력받고, 정렬하고, 순위를 측정한 뒤 출력하는 것을 반복한다.
4. 총점배열로도 정렬, 순위 측정, 출력한다.
public static void main(String args[]) throws Exception
{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(in.readLine());
StringTokenizer st;
StringBuilder sb = new StringBuilder();
Score[] total = new Score[N];
for(int i=0;i<N;i++) total[i] = new Score(i,0);
Score[] current = new Score[N];
for(int i=0;i<3;i++){
st = new StringTokenizer(in.readLine());
//입력
for(int j=0;j<N;j++){
current[j] = new Score(j,Integer.parseInt(st.nextToken()));
total[j].score+=current[j].score;
}
//순위
int[] tmp = setOrder(current);
//출력
for(int j=0;j<N;j++){
sb.append(tmp[j]).append(' ');
}
sb.append('\n');
}
//전체점수 순위출력
int[] tmp = setOrder(total);
for(int j=0;j<N;j++){
sb.append(tmp[j]).append(' ');
}
System.out.println(sb);
}
전체 코드
import java.util.*;
import java.io.*;
public class Main
{
static int N;
public static void main(String args[]) throws Exception
{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(in.readLine());
StringTokenizer st;
StringBuilder sb = new StringBuilder();
Score[] total = new Score[N];
for(int i=0;i<N;i++) total[i] = new Score(i,0);
Score[] current = new Score[N];
for(int i=0;i<3;i++){
st = new StringTokenizer(in.readLine());
//입력
for(int j=0;j<N;j++){
current[j] = new Score(j,Integer.parseInt(st.nextToken()));
total[j].score+=current[j].score;
}
//순위
int[] tmp = setOrder(current);
//출력
for(int j=0;j<N;j++){
sb.append(tmp[j]).append(' ');
}
sb.append('\n');
}
//전체점수 순위출력
Arrays.sort(total);
int[] tmp = setOrder(total);
for(int j=0;j<N;j++){
sb.append(tmp[j]).append(' ');
}
System.out.println(sb);
}
public static int[] setOrder(Score[] current){
Arrays.sort(current);
int[] tmp = new int[N];
int order = 1;
tmp[current[0].idx] = order;
for(int j=1;j<N;j++){
if(current[j-1].score != current[j].score){
order = j+1;
}
tmp[current[j].idx] = order;
}
return tmp;
}
static class Score implements Comparable<Score> {
int idx;
int score;
public Score(int idx, int score){
this.idx = idx;
this.score = score;
}
public int compareTo(Score o){
return o.score-this.score;
}
}
}
3. 결과
setOrder에 정렬을 넣지 않고 main에서 진행했는데, current말고 total에도 정렬해야하는 걸 잊어서 틀렸다.
'코딩테스트 > ELSE' 카테고리의 다른 글
[Softeer] 장애물 인식 프로그램 - JAVA (0) | 2023.05.10 |
---|---|
[CODILITY] BinaryGap - Java (0) | 2023.03.19 |
[Softeer] 성적 평균 - JAVA (0) | 2023.02.05 |
[Softeer] 금고털이 - JAVA (0) | 2023.02.03 |
[JO] 1658 최대공약수와 최소공배수 (0) | 2022.07.31 |
댓글