본문 바로가기
Algorithm/프로그래머스

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

by code_pie 2024. 3. 19.
 
 

풀이

 

[문제 풀이]

 

이 문제는 특정 사원보다 근무 태도 점수와 동료 평가 점수가 낮은 사원을 등수에서 제외하는게 핵심인 문제다.

그렇기 때문에 정렬만 잘 하면 쉽게 해결할 수 있다.

 

먼저 인사고과 중 근무 태도 점수와 동료 평가 점수 중 하나를 기준으로 정렬을 한다.

 

예를 들어 근무 태도점수를 기준으로 내림차순으로 정렬을 한다고 가정하자.

위 그림과 같이 정렬이 됐다면, 탐색을 시작한다.

근무 태도 점수는 이미 정렬이 됐으므로 중요한 점수는 동료 평가 점수이다.

여기서 prevMax와 nowMax 두 변수를 사용하는 이유는 근무 평가 점수가 같을 수 있기 때문이다.

A 직원이 B직원보다 동료 평가 점수가 높아도 A직원과 B직원의 근무평가 점수가 같다면 인센티브를 받을 수 있다.

 

그러므로 여기서 prevMax는 나보다 근무 평가 점수가 높은 사람들 중 가장 높은 동료 평가 점수를 저장하고, nowMax는 현재까지 탐색한 사람들 중 가장 높은 동료 평가 점수를 저장한다.

 

이후 근무 평가 점수가 달라지면 이전 사람들은 전부 나보다 근무평가가 높으므로 동료 평가 점수를 높여서 비교한다.

(그림을 참고하면 이해가 쉽다)

 

이렇게 탐색할 경우 근무평가는 항상 정렬 돼 있으므로, 현재 사람의 동료평가 점수와 저장된 prevMax값만 비교한다.

만약 prevMax가 현재 사람의 동료평가 점수보다 높다면 인센티브를 못 받는다는 뜻이므로 pass한다.

 

만약 현재 사람의 동료평가 점수가 prevMax와 같거나 크다면 완호의 총 점수와 비교하고, 총 점수가 더 높으면 완호보다 등수가 높으므로 완호의 등수를 1올리면 된다.

 

이후 최종적으로 평가된 완호의 등수를 return한다. 

 

[아이디어 정리]

  1. 근무평가 점수를 기준으로 내림차순 정렬을 한다.
  2. 현재 사람의 동료평가 점수를 nowMax와 비교해 가장 큰 값으로 갱신한다.
  3. 근무평가 점수가 높은 순서로 탐색을 하며 만약 이전사람과 근무평가 점수가 다르면 지금까지 저장된 동료평가 점수의 가장 큰 값을 prevMax에 갱신한다. 
  4. prevMax와 현재 사람의 동료평가 점수를 비교하고 만약 prevMax보다 크거나 같다면, 완호의 점수와 비교한다.
  5. 완호보다 점수가 크면 완호의 등수가 밀리므로 완호의 등수를 1 늘린다.
  6.  최종적으로 저장된 완호의 등수를 return한다.

+코드1이 좀 더 직관적인 코드이므로 이해하기 더 편하다

 

 

Code (직관적)

 

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

int solution(vector<vector<int>> scores) {
    int answer = 1; //등수
    int s0=scores[0][0],s1=scores[0][1]; //완호의 점수
    int hap=s0+s1; //완호의 점수 합
    vector<vector<int>>newScores;
    sort (scores.begin(),scores.end(),[](vector<int> a, vector<int>b){//정렬
        if (a[0]==b[0])
        {
            return a[1]>b[1];
        }
        return a[0]>b[0];
    });
    int prevMax=0,nowMax=scores[0][1];
    newScores.push_back(scores[0]);
    for (int i=1; i<scores.size(); i++) //비교 후 인센티브를 받으면 newScores에 push
    {
        if (scores[i][0]<scores[i-1][0])// 근무 평가 점수가 바뀌면(앞 사람이 더 높으면)
        {                              // 동료평가 점수(prevMax값)을 nowMax로 갱신한다.
            prevMax=nowMax;
        }
        if (scores[i][1]>=prevMax)
        {
            newScores.push_back(scores[i]);
        }
        nowMax=max(nowMax,scores[i][1]); //항상 최대값으로 갱신한다
    }
    
    for (int i=0; i<newScores.size(); i++)
    {
        if (newScores[i][0]>s0 && newScores[i][1]>s1) //완호보다 두 점수가 높은 직원이 있으면 -1
        {
            return -1;
        }      
        if(hap<newScores[i][0]+newScores[i][1]) //완호보다 두 점수의 합이 높으면 등수가 밀린다.
        {
            answer+=1;
        }  
    }    
    
    return answer;
}

 

 

Code2

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

int solution(vector<vector<int>> scores) {
    int answer = 1;
    int s0=scores[0][0],s1=scores[0][1];
    int hap=s0+s1;
    vector<vector<int>>newScores;
    sort (scores.begin(),scores.end(),[](vector<int> a, vector<int>b){
        if (a[0]==b[0])
        {
            return a[1]>b[1];
        }
        return a[0]>b[0];
    });
    int prevMax=0,nowMax=scores[0][1];
    if (scores[0][0]>s0 && scores[0][1]>s1)
    {
        return -1;
    }  
    if (hap<scores[0][0]+scores[0][1])
        answer+=1;
    for (int i=1; i<scores.size(); i++)
    {
        if (scores[i][0]<scores[i-1][0])
        {
            prevMax=nowMax;
        }
        if (scores[i][1]>=prevMax)
        {
            if (hap<scores[i][0]+scores[i][1])
            {
                answer+=1;
            }
        }
        if (scores[i][0]>s0 && scores[i][1]>s1)
        {
            return -1;
        }      
        nowMax=max(nowMax,scores[i][1]);
    }
    
    return answer;
}

 


처음에 근무평가가 같은 사람중에 동료평가가 높은 경우를 고려하지 않았다.

정렬만 잘 하면, 비교할 인자가 하나만 남기 때문에 쉽게 풀 수 있는 문제였다.

 

프로그래머스

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

programmers.co.kr

 

반응형