N

(프로그래머스 c++)위클리 챌린지 6주차 본문

프로그래머스 알고리즘/Weekly Challenge

(프로그래머스 c++)위클리 챌린지 6주차

naeunchan 2021. 9. 7. 00:16
728x90
반응형

https://programmers.co.kr/learn/courses/30/lessons/85002?language=cpp 

 

코딩테스트 연습 - 6주차

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

programmers.co.kr

 

 

기본적인 STL을 모두 사용한 것 같다..ㅎㅎ

vector, map, set, pair를 사용했으며, 정렬을 위한 algorithm 헤더까지 사용했다.

 

정렬의 우선순위가

승률 > 자신보다 무거운 사람을 이긴 수 > 자신의 몸무게 등수 > 자신의 인덱스 번호

로 되어 있다.

 

정렬을 하기 전, 복서들의 몸무게 등수를 알수 있도록 set과 map을 이용해 처리하도록 하자.

set은 중복된 값은 하나로 처리하고 오름차순으로 정렬한다.

이 set을 이용해 map으로 복서들의 몸무게 순위를 매길 수 있다.

 

이중 for문으로 weights와 head2head를 순회하자.

total과 win은 한 복서가 경기를 한 횟수와 이긴 횟수를 나타낸다.

win / total이 소수점으로 나와야 하기 때문에 둘 다 double로 선언.

 

heavier는 자신의 몸무게보다 무거운 사람을 이긴 횟수를 나타낸다.

index는 자신의 몸무게 등수를 나타낸다.

 

i의 복서와 j의 복서의 경기 결과가 head2head에 나와있으며,

'W'이 나오면 win++을 해주고, weights[i]와 weights[j]를 비교해 i쪽이 더 크면 heavier++을 한다.

'N'이 나오면 total--을 해주어 경기를 하지 않았다는 것을 카운팅한다.

 

inner for문이 끝나면 total이 0인지 확인하도록 하자.

0이라면 아무런 경기를 뛰지 않았기 때문에 rate도 0이 된다.(나눗셈의 예외처리가 발생하기 때문)

1 이상이라면 rate = win / total을 해주도록 한다.

 

이제 정렬의 우선순위처럼 rating 벡터에 넣어주도록 하자.

{{승률(rating), 무거운 사람 이긴 횟수(heavier)}, {자신의 몸무게 순위(index), 자신의 인덱스(i)}}

 

이 rating 벡터를 desc() 함수에 맞춰 정렬을 하면 된다.

 

 

#include <string>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <iostream>

#define PAIR pair<pair<double, int>, pair<int, int>>

using namespace std;

bool desc(PAIR a, PAIR b){
    if(a.first.first == b.first.first){
        if(a.first.second == b.first.second){
            if(a.second.first == b.second.first){
                return a.second.second < b.second.second;
            }
            
            return a.second.first > b.second.first;
        } 
        
        return a.first.second > b.first.second;
    }
    
    return a.first.first > b.first.first;
}

vector<int> solution(vector<int> weights, vector<string> head2head) {
    vector<int> answer;
    vector<PAIR> rating;
    set<int> weightsSet;
    map<int, int> weightsMap;
    int size = weights.size();
    int rank = 0;
        
    for(int i = 0; i < size; i++){
        weightsSet.insert(weights[i]);
    }
    
    for(auto itr = weightsSet.begin(); itr != weightsSet.end(); itr++){
        weightsMap[*itr] = rank++;
    }
    
    for(int i = 0; i < size; i++){
        double total = size;
        double win = 0;
        int heavier = 0;
        int index = weightsMap[weights[i]];
        double rate = 0;
        
        for(int j = 0; j < size; j++){
            if(head2head[i][j] == 'W'){
                if(weights[i] < weights[j]){
                    heavier++;
                }
                win++;
            } else if(head2head[i][j] == 'N'){
                total--;
            }
        }
        
        if(total == 0){
            rate = 0;
        }else{
            rate = win / total;
        }
        rating.push_back({{rate, heavier}, {index, i}});
    }
    
    sort(rating.begin(), rating.end(), desc);
    
    for(auto itr = rating.begin(); itr != rating.end(); itr++){
        // cout << itr->first.first << " " << itr->first.second << " " << itr->second.first << " " << itr->second.second << endl;
        answer.push_back(itr->second.second + 1);
    }
    
    return answer;
}
728x90
반응형