[프로그래머스] 위클리챌린지 6주차 복서 정렬하기
https://programmers.co.kr/learn/courses/30/lessons/85002?language=java
코딩테스트 연습 - 6주차_복서 정렬하기
복서 선수들의 몸무게 weights와, 복서 선수들의 전적을 나타내는 head2head가 매개변수로 주어집니다. 복서 선수들의 번호를 다음과 같은 순서로 정렬한 후 return 하도록 solution 함수를 완성해주세요
programmers.co.kr
요즘에 맨날 백준을 풀다가 오랜만에 프로그래머스를 들어가 보았다. 그동안 위클리챌린지도 많이 올라왔는데 얼른 풀어봐야겠다. 이 문제는 Collection 혹은 2차원 배열처럼 다중 자료구조를 정렬하는 법을 알고 있는 지를 물어보는 문제라고 생각한다. 나는 별도의 클래스를 만들어서 해결했는데 나중에 생각해보니 2차원 배열로 해결이 가능할 것 같다.
1. 함수의 파라미터로 전달받은 weights, head2head를 문제에 맞게 종류별로 각각 전처리해준다.
1-1. win : 승률은 이긴 경기 수/전체 경기 수가 아닌, 이긴 경기 수/유효한 경기 수(N이 아닐 떄)로 나눠야한다.
1-2. weightWin : head2head의 값 중, W인 인덱스를 찾아서 내 몸무게와 해당 인덱스의 선수 몸무게를 비교해서 상대방 몸무게가 많으면 + 한다.
1-3. myWeight : weights 배열을 그대로 가져온다.
1-4. num : 선수 개개인의 번호이고, 인덱스 i를 사용한다.
2. 미리 선언한 player 클래스에 해당 값들을 저장한다.
2-1. 이 때, 유효 경기를 나타내는 변수 cnt나 이긴 횟수 win가 0이라면 강제로 0을 넣어준다.
2-2. 나머지의 경우에는 double로 강제 형변환을 해준 후, 이긴 경기 수/유효 경기 수 (=win/cnt)로 넣어준다.
3. 해당 ArrayList를 조건에 맞게 정렬한다.
3-1. 조건순위 1 : 승률 비교 내림차순
3-2. 조건순위 2 : 나보다 몸무게가 많은 선수를 이긴횟수 내림차순
3-3. 조건순위 3 : 몸무게 내림차순
3-4. 조건순위 4 : 선수번호 오름차순 <- 주의한다.
4. 결과 배열 result를 만들고 선수번호를 넣어서 출력한다.
문제 및 제한사항
입출력 예
코드
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class Solution
{
// 선수데이터를 나타내는 클래스 선언
public static class player
{
double win; // 승률
int weightWin; // 나보다 몸무게가 무거운 복서를 이긴 횟수
int weight; // 몸무게
int num; // 선수번호
player(double win, int weightWin, int weight, int num)
{
this.win = win;
this.weightWin = weightWin;
this.weight = weight;
this.num = num;
}
}
public static int[] solution(int[] weights, String[] head2head)
{
ArrayList<player> list = new ArrayList<player>();
// 데이터 전처리
for(int i=0; i<head2head.length; i++)
{
int num = i+1;
int myWeight = weights[i];
int win = 0;
int weightWin = 0;
int cnt = 0;
for(int j=0; j<head2head[0].length(); j++)
{
// N이 아닌 경우에는 경기 수로 +
if(head2head[i].charAt(j)!='N')
{
cnt++;
}
// W일 경우에는 이긴 경기 수로 +
if(head2head[i].charAt(j)=='W')
{
win++;
// 이긴 경기 중, 해당 선수 몸무게가 나보다 클 경우 weightWin +
if(weights[j]>myWeight)
{
weightWin++;
}
}
}
// 예외처리 : 해당 선수가 모두 경기를 하지 않는 N이거나, 이긴 경우가 없을때
if(cnt==0 || win==0)
{
list.add(new player(0, weightWin, myWeight, num));
}
else
{
list.add(new player((double)win/cnt, weightWin, myWeight, num));
}
}
// 조건에 맞는 정렬
Collections.sort(list, new Comparator<player>()
{
@Override
public int compare(player x, player y)
{
// 조건순위 1 : 승률 비교
if(x.win!=y.win)
{
return Double.compare(y.win, x.win);
}
else
{
// 조건순위 2 : 나보다 몸무게가 많은 선수를 이긴횟수
if(x.weightWin!=y.weightWin)
{
return Integer.compare(y.weightWin, x.weightWin);
}
else
{
// 조건순위 3 : 몸무게
if(x.weight!=y.weight)
{
return Integer.compare(y.weight, x.weight);
}
else
{
// 조건순위 4 : 선수번호
return Integer.compare(x.num, y.num);
}
}
}
}
});
// 결과배열을 선언하고 선수번호를 넣어서 출력
int[] result = new int[list.size()];
for(int i=0; i<list.size(); i++)
{
result[i] = list.get(i).num;
}
return result;
}
}