본문 바로가기
Algorithm/Weekly Solved

[위클리챌린지] 6주 - 복서 정렬하기 - Java코드

https://programmers.co.kr/learn/courses/30/lessons/85002#qna

 

코딩테스트 연습 - 6주차_복서 정렬하기

복서 선수들의 몸무게 weights와, 복서 선수들의 전적을 나타내는 head2head가 매개변수로 주어집니다. 복서 선수들의 번호를 다음과 같은 순서로 정렬한 후 return 하도록 solution 함수를 완성해주세요

programmers.co.kr

 

 

문제

 

이해

객체 정렬 문제이다.

승률 > 무거운 사람을 이긴 횟수 > 내 몸무게 > 순번

순서로 복서를 정렬해주면된다

 

객체를 만드는게 깔끔하지만,

1000명 이하의 input이 정해져있으므로

사용이 편한 이차원배열로 문제를 풀었다.

 

포인트

자바로 푸는경우,

핵심은 Arrays.sort에 comparator사용하여

자신이 원하는대로 정렬을 할 수 있는가에 대한 문제이다.

 

추가적으로 문제를 푸는과정에서 승률은 매우 중요했다.

올바르고 정확한 승률비교를 위해 double형 사용이 필요하다.

 

나는 char 카운트를 위해 Stream객체의 filter, count 등을 사용하여 깔끔하게 구해보려 시도하였다.

풀이

import java.util.Arrays;
import java.util.Comparator;
class Solution {
    public static int[] solution(int[] weights, String[] head2head) {
    double wins[][] = new double[weights.length][4];
    for(int i=0;i<weights.length;i++) {
      double win = (double) head2head[i].chars().filter(c->c=='W').count();
      double lose = (double) head2head[i].chars().filter(c->c=='L').count();
      double p=0;
      if(win+lose==0) p=0;
      else p=(double)win/(win+lose)*100;
      wins[i][0] = p;
      wins[i][1] = countBigWin(weights, head2head[i], i);
      wins[i][2] = weights[i];
      wins[i][3] = i;
    }
    Arrays.sort(wins,new Comparator<double[]>(){
      @Override
      public int compare(double[] o1, double[] o2) {
        if(o2[0]==o1[0]) { // 승률이 같으면
          if(o2[1]==o1[1]) { // 무거운사람 이긴수도 같으면
            if(o2[2]==o1[2]) // 몸무게도 같으면
              return (int)(o1[3]-o2[3]);  // 앞번호 순으로 정렬
            else
              return (int)(o2[2]-o1[2]);
          }
          else 
            return (int) (o2[1]-o1[1]);
        }
        else if(o2[0] - o1[0]<0) // 내림차순 정렬 
          return -1;
        else
          return 1;
      }
    });
    int[] result= new int [weights.length];
    for(int i=0;i<wins.length;i++) 
      result[i] = (int)wins[i][3]+1;
    return result;
  }
  public static int countBigWin(int[] weight, String s,int index) {
    int cnt=0;
    for(int i=0;i<s.length();i++)
      if(s.charAt(i)=='W' && weight[index]<weight[i])
        cnt++;
    return cnt;
  }
}

 

다른사람의 풀이

import java.util.*;
class Solution {
    public int[] solution(int[] weights, String[] head2head) {
        int len = weights.length;
        int[][] rank = new int[len][4];
        for(int i = 0; i < len; i++) {
            int w = weights[i], cnt = 0, win = 0, over = 0;
            for(int j = 0; j < len; j++) {
                char c = head2head[i].charAt(j);
                cnt += c == 'N' ? 0 : 1;
                win += c == 'W' ? 1 : 0;
                over += c == 'W' && weights[i] < weights[j] ? 1 : 0;
            }
            rank[i][0] = i + 1;
            rank[i][1] = (int)((double)win / cnt * 10000000);
            rank[i][2] = over;
            rank[i][3] = weights[i];
        }
        Arrays.sort(rank, (a, b) -> {
            if(a[1] != b[1]) return b[1] - a[1];
            if(a[2] != b[2]) return b[2] - a[2];
            if(a[3] != b[3]) return b[3] - a[3];
            return a[0] - b[0];
        });
        int[] answer = new int[len];
        for(int i = 0; i < len; i++) answer[i] = (int)rank[i][0];
        return answer;
    }
}

 

깔끔하신데,

승률을 구할때 정확성은 버리셨다.

100이 아닌 더 큰수를 곱해서

소수점아래를 몇개 더 살려 int형 이차원배열에 꾸역꾸역 넣으셨지만,

 

올바른 풀이는 아니다.

테케에 걸리지 않은건 운이 좋은것뿐 정확한 답을내는 코드라고 할 수 없다.

 

그치만, 전체적으로 본받을만하다.

if문으로 차례차례 깔끔하게 처리한게 인상적이다.