[프로그래머스/C++] 복서 정렬하기

연성·2021년 9월 7일
0

코딩테스트

목록 보기
236/261
post-thumbnail
post-custom-banner

[프로그래머스/C++] 복서 정렬하기

1. 문제

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

  1. 전체 승률이 높은 복서의 번호가 앞쪽으로 갑니다. 아직 다른 복서랑 붙어본 적이 없는 복서의 승률은 0%로 취급합니다.
  2. 승률이 동일한 복서의 번호들 중에서는 자신보다 몸무게가 무거운 복서를 이긴 횟수가 많은 복서의 번호가 앞쪽으로 갑니다.
  3. 자신보다 무거운 복서를 이긴 횟수까지 동일한 복서의 번호들 중에서는 자기 몸무게가 무거운 복서의 번호가 앞쪽으로 갑니다.
  4. 자기 몸무게까지 동일한 복서의 번호들 중에서는 작은 번호가 앞쪽으로 갑니다.

2. 제한사항

  • weights의 길이는 2 이상 1,000 이하입니다.
    • weights의 모든 값은 45 이상 150 이하의 정수입니다.
    • weights[i] 는 i+1번 복서의 몸무게(kg)를 의미합니다.
  • head2head의 길이는 weights의 길이와 같습니다.
    • head2head의 모든 문자열은 길이가 weights의 길이와 동일하며, 'N', 'W', 'L'로 이루어진 문자열입니다.
    • head2head[i] 는 i+1번 복서의 전적을 의미하며, head2head[i][j]는 i+1번 복서와 j+1번 복서의 매치 결과를 의미합니다.
    • 'N' (None)은 두 복서가 아직 붙어본 적이 없음을 의미합니다.
    • 'W' (Win)는 i+1번 복서가 j+1번 복서를 이겼음을 의미합니다.
    • 'L' (Lose)는 i+1번 복사가 j+1번 복서에게 졌음을 의미합니다.
    • 임의의 i에 대해서 head2head[i][i] 는 항상 'N'입니다. 자기 자신과 싸울 수는 없기 때문입니다.
    • 임의의 i, j에 대해서 head2head[i][j] = 'W' 이면, head2head[j][i] = 'L'입니다.
    • 임의의 i, j에 대해서 head2head[i][j] = 'L' 이면, head2head[j][i] = 'W'입니다.
    • 임의의 i, j에 대해서 head2head[i][j] = 'N' 이면, head2head[j][i] = 'N'입니다.

3. 풀이

  • Boxer class를 만들었다.
class Boxer {
    public:
    int index;   
    double winRate;
    int weight;
    int win2heavierBoxer;
    Boxer(int index, double winRate, int weight, int win2heavierBoxer) {
        this->index = index;
        this->winRate = winRate;
        this->weight = weight;
        this->win2heavierBoxer = win2heavierBoxer;
    }
};
  • 특별한 점은 없고 클래스로 만들면 저장하기 편하고 정렬하기 편하다.
  • head2head 배열을 탐색하면서 승률과 자기보다 무거운 사람과 싸운 횟수 등을 계산한다.
  • 모든 값을 구하면 Boxer 배열에 값을 집어넣는다,
  • 정렬한 후에 인덱스 값만 추출해서 answer 배열에 삽입한다.

4. 처음 코드와 달라진 점

  • 분모가 0인 경우가 있어서 해당 경우를 처리해주었다.
    • winRate 변수를 만들고 분모가 0일 경우 계산을 하지 않고 값을 0으로 만들었다.
        double winRate = numberOfFight == 0 ? 0 : double(numberOfWin) / double(numberOfFight);
  • 맨날 오름차순으로만 정렬하다보니 기호를 반대로 써서 수정해주었다.

5. 코드

#include <string>
#include <vector>
#include <algorithm>

using namespace std;

class Boxer {
    public:
    int index;   
    double winRate;
    int weight;
    int win2heavierBoxer;
    Boxer(int index, double winRate, int weight, int win2heavierBoxer) {
        this->index = index;
        this->winRate = winRate;
        this->weight = weight;
        this->win2heavierBoxer = win2heavierBoxer;
    }
};

bool compare(Boxer &a, Boxer &b) {
    if (a.winRate == b.winRate) {
        if (a.win2heavierBoxer == b.win2heavierBoxer) {
            if (a.weight == b.weight) {
                return a.index < b.index;
            }
            return a.weight > b.weight;
        }
        return a.win2heavierBoxer > b.win2heavierBoxer;
    }
    return a.winRate > b.winRate;
}

vector<int> solution(vector<int> weights, vector<string> head2head) {
    vector<int> answer;
    vector<Boxer> arr;

    for (int i = 0 ; i < head2head.size(); ++i) {
        int numberOfFight = 0;
        int numberOfWin = 0;
        int numberOfwin2heavierBoxer = 0;
        for (int j = 0; j < head2head[i].size(); ++j) {
            if (head2head[i][j] == 'N') continue;
            
            numberOfFight++;
            if (head2head[i][j] == 'W') {
                numberOfWin++;
                if (weights[i] < weights[j]) {
                    numberOfwin2heavierBoxer++;
                }
            }
        }
        double winRate = numberOfFight == 0 ? 0 : double(numberOfWin) / double(numberOfFight);
        arr.push_back(Boxer(i + 1, winRate, weights[i], numberOfwin2heavierBoxer));
    }
    
    sort(arr.begin(), arr.end(), compare);
    for (int i = 0; i < arr.size(); ++i) {
        answer.push_back(arr[i].index);
    }
    
    return answer;
}
post-custom-banner

0개의 댓글