Programmers/Level 3

C++ / 프로그래머스 / 인사고과

GitHubSeob 2023. 6. 27. 17:47

문제

https://school.programmers.co.kr/learn/courses/30/lessons/152995

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

문제풀이

순위는 근무 태도 점수 + 동료 평가 점수의 합산으로 정한다.

본인보다 근무 태도 점수, 동료 평가 점수 둘 다 높은 사람이 있는 경우, 순위에서 제외된다.

 

이중 반복문을 통해 합을 내림차순으로 탐색하면서, 다른 점수들과 비교하면서 순위에서 제외되는지를 판단했다.

 

    int idx(0), rank(1), cnt(0);
    int sum(0), work(0), peer(0), prev(0);
    bool pass(false);

    multimap<int, int, greater<int>>m;
    map<int, int, greater<int>>max_num;

rank는 answer대신 순위를 나타내는 변수, cnt는 동석차 수를 나타내는 변수이다.

sum은 두 점수의 합, work는 근무 태도 점수, peer은 동료 평가 점수, prev는 동석차를 구분하기 위한 이전 사원 평가점수이다.

pass는 순위에서 제외되는지를 알려주는 bool형태의 변수이다.

 

m은 key = 두 점수의 합, value = 동료 평가 점수를 인자로 갖는 map이다.

max_num은 key = 근무 태도 점수, value = 동료 평가 점수를 인자로 갖는 map이다.

max_num에는 근무 태도 점수가 같다면 가장 점수가 높은 동료 평가 점수를 넣었다

 

    m.insert({ scores[0][0] + scores[0][1], scores[0][1] });

    for (idx = 0; idx < scores.size(); ++idx) {
        if (scores[0][0] + scores[0][1] < scores[idx][0] + scores[idx][1]) {
            m.insert({ scores[idx][0] + scores[idx][1], scores[idx][1] });
        }
        if (scores[0][0] < scores[idx][0] && scores[0][1] < scores[idx][1]) {
            return -1;
        }
    }

scores[0][0]은 완호의 점수이다.

m에 완호의 점수를 입력한다.

 

for문을 통해 점수들을 탐색하면서 완호의 두 점수의 합보다 높은 사원들만 m에 입력한다.

만약 완호의 두 점수보다 높은 두 점수의 사원이 나온다면, 완호는 인센티브를 못 받으므로 -1을 return 한다.

 

    for (auto it = m.begin(); it != m.end(); ++it) {
        sum = it->first;
        work = sum - it->second;
        peer = it->second;
        for (auto iter = max_num.begin(); iter != max_num.end(); ++iter) {
            if (work < iter->first && peer < iter->second) {
                pass = true;
                break;
            }
        }
        if (pass == true) {
            pass = false;
            continue;
        }

m이 기준으로 삼을 사원, max_num이 비교할 사원이다.

현재 사원의 두 점수보다 큰 두 점수의 사원이 있다면 pass를 true로 바꾸고 비교를 멈춘다.

 

그다음 pass를 다시 바꾸고 순위에서 제외하고 다음 사원으로 넘어간다.

 

        if (max_num[work] == 0) {
            max_num[work] = peer;
        }

        if (prev == sum) {
            cnt++;
        }
        else {
            rank += cnt;
            cnt = 1;
        }

        prev = sum;
    }

위의 이어진 코드이다.

근무 태도 점수 기준으로 가장 높은 점수의 평가 점수를 나타내기 위해 0이라면 점수를 입력한다.

max_num[work]가 비어있다면 동료 평가 점수를 채운다.

합의 내림차순으로 탐색하기 때문에 비어 있지 않다면, 동료 평가 점수는 낮다.

 

prev가 sum과 같다면 동석차이므로 cnt++을 한다.

다르다면 순위에 동석차 사원들의 수를 더하고 동석차를 초기화한다.

 

prev를 현재 사원의 점수로 바꾼다.

 

 

코드

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

int solution(vector<vector<int>> scores) {
    int idx(0), rank(1), cnt(0);
    int sum(0), work(0), peer(0), prev(0);
    bool pass(false);

    multimap<int, int, greater<int>>m;
    map<int, int, greater<int>>max_num;

    m.insert({ scores[0][0] + scores[0][1], scores[0][1] });

    for (idx = 0; idx < scores.size(); ++idx) {
        if (scores[0][0] + scores[0][1] < scores[idx][0] + scores[idx][1]) {
            m.insert({ scores[idx][0] + scores[idx][1], scores[idx][1] });
        }
        if (scores[0][0] < scores[idx][0] && scores[0][1] < scores[idx][1]) {
            return -1;
        }
    }

    for (auto it = m.begin(); it != m.end(); ++it) {
        sum = it->first;
        work = sum - it->second;
        peer = it->second;
        for (auto iter = max_num.begin(); iter != max_num.end(); ++iter) {
            if (work < iter->first && peer < iter->second) {
                pass = true;
                break;
            }
        }
        if (pass == true) {
            pass = false;
            continue;
        }
        if (max_num[work] == 0) {
            max_num[work] = peer;
        }

        if (prev == sum) {
            cnt++;
        }
        else {
            rank += cnt;
            cnt = 1;
        }

        prev = sum;
    }
    return rank;
}