본문 바로가기
코딩테스트 공부/Programmers

[C++] 위클리챌린지 6주차 복서 정렬하기 85002

by 메정 2021. 9. 6.

📌문제

/* 해당 문제 설명은 링크로 대체한다. */

📌풀이

vector<pair<int, pair<int, int>>> score; //first : idx, second-first : 이긴 횟수, second-second : 승률

다음과 같은 vector 변수를 저장해두고, weight 배열을 돌면서 각 idx 별 승률과 이긴 횟수를 구해 score에 넣어주었다.
그리고 score를 정렬 조건에 맞춰 정렬해준 다음 answer에는 idx 값만 추가하여 return 하는 방식으로 풀었다.

문제 자체는 어렵지 않으나 승률 구하기와 정렬에 주의해야 한다!

vector에 weight 값도 같이 넣어주면 더 정렬이 깔끔해지고 불필요한 temp 변수를 사용하지 않아도 될 것 같은데 vector에 3개 이상 넣어서 정렬해본 적이 없어서 따로 빼서 계산하는 식으로 구하였다....... 더 좋은 방법이 있다면 댓글로 알려주시면 감사할 것 같다.

📌코드

#include <string>
#include <vector>
#include <algorithm>
using namespace std;

vector<int> temp; //비교함수에서 무게 기준 정렬 구하기 위함

bool cmp(pair<int, pair<int, int>> a, pair<int, pair<int, int>> b)
{
    if (a.second.second > b.second.second) //1. 능률 높은 순으로 정렬
        return true;
    else if (a.second.second == b.second.second)
    { //2. 능률이 같을 경우 이긴 횟수 기준으로 정렬
        if (a.second.first > b.second.first)
            return true;
        else if (a.second.first == b.second.first) //3. 이긴 횟수가 같을 경우 무게 기준 정렬
            if (temp[a.first - 1] > temp[b.first - 1])
                return true;
            else if (temp[a.first - 1] == temp[b.first - 1]) //4. 무게 기준도 같을 경우 idx 오름차순 정렬
                return a.first < b.first;
            else
                return false;
        else
            return false;
    }
    else
        return false;
}

vector<int> solution(vector<int> weights, vector<string> head2head)
{
    temp = weights; //복사

    vector<int> answer;
    vector<pair<int, pair<int, int>>> score; //first : idx, second-first : 이긴 횟수, second-second : 승률

    int bigThen = 0, fight_total = 0;
    double winningRate = 0, winCnt = 0;
    for (int i = 0; i < weights.size(); i++)
    {
        winCnt = 0; //이긴 횟수
        for (int j = 0; j < head2head.size(); j++)
        {
            if (head2head[i][j] != 'N')
                fight_total++;

            if (i != j && head2head[i][j] == 'W')
            { //이김
                winCnt++;
                if (weights[i] < weights[j])
                    bigThen++;
            }
        }
        //승률을 계산해서 배열에 넣음
        if (fight_total > 0)
            winningRate = (winCnt / fight_total) * 1000000000;
        score.push_back({i + 1, {bigThen, winningRate}});

        //초기화
        fight_total = 0;
        winCnt = 0;
        winningRate = 0;
        bigThen = 0;
    }

    //조건 정렬
    sort(score.begin(), score.end(), cmp);

    for (auto s : score)
        answer.push_back(s.first);

    return answer;
}

회고
아주 조금씩 천천히 실력이 늘고 있는 것 같기도 하다 ..... 헤헤 ..... 긍정긍정 .....
정렬부분이 깔끔하지 못해서 조금 마음에 걸린다.......... 다음에 리팩토링 해보아야지!

문제 자체는 빨리 풀었는데 자꾸 tc 6 ~ 11 에서 실패가 나서 질문하기 보니까 승률 계산 문제일 수 있다고 해서
처음엔 x1000을 해주다가 0을 점점 늘렸더니 ... 됐다 ........ 아무래도 tc 6 ~ 11 문제의 경우 숫자가 겁나게 큰가보다...

댓글