[프로그래머스 C++] 야근 지수

 

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

 

프로그래머스

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

programmers.co.kr


 

 

해결방안

 

우선순위 큐 priority_queue

힙 Heap

 

 

이 문제의 핵심은 "작업량을 최대한 균등하게 줄여서 남은 작업량의 제곱 합을 최소화하는 것"이다.

 

  • 남은 작업량을 최대한 균등하게 줄여야 한다.
  • 최대 힙을 사용해 현재 가장 작업량이 많은 일을 1만큼 줄이고, 다시 힙에 넣는 과정을 반복한다.
  • 이렇게 하면 작업량이 많은 일부터 줄어들게 되고, 전체 작업량이 균등하게 분배된다.
  • 정리해서 다시 말하면, 가장 큰 작업량을 줄이면서 남은 작업량의 제곱 합을 최소화 했다.

 

 

정답 코드

 

#include <iostream>
#include <queue>
#include <algorithm>
#include <cmath>
using namespace std;

long long solution(int n, vector<int> works) {
    long long answer = 0;

    priority_queue<int> pQ; // 최대 힙을 이용해 작업량이 많은 순서대로 처리

    int total = 0; // 전체 작업량
    for(int i = 0; i < works.size(); i++){
        total += works[i];
        pQ.push(works[i]); // 최대 힙에 작업량을 추가
    }

    if (total <= n) return 0; // 남은 작업량이 소진할 수 있는 야근 시간보다 적거나 같으면 피로도는 0


    while (!pQ.empty() && n > 0) { // 힙이 비어있지 않고 n이 0보다 클 때까지 반복
        int top = pQ.top(); // 최대 작업량을 가져옴
        pQ.pop(); 			// 최대 작업량을 힙에서 제거

        n--; 				// 야근 시간 1시간 소진
        top--; 				// 최대 작업량 1시간 소진
        pQ.push(top);   	// 줄어든 작업량을 다시 힙에 추가
    }

    while(!pQ.empty()) {
        int top = pQ.top();
        pQ.pop(); 			

        answer += pow(top, 2); // 작업량의 제곱을 더해서 피로도를 계산
    }

    return answer; // 최종 피로도를 반환
}

int main(){
    cout << solution(4, { 4, 3, 3 }) << "\n";
    cout << solution(1, { 2, 1, 2 }) << "\n"; 
    cout << solution(3, { 1, 1 }) << "\n"; 

    return 0;
}