study
광물 캐기[프로그래머스]
Date: 2026-05-29 11:32
Update: 2026-05-29 11:46


광물 캐기[프로그래머스]

접근법:

  1. 곡괭이 갯수를 토대로 최대로 캘수있는 광물의 갯수를 정한다.
    1. 들고있는 곡괭이로 캘수 있는 만큼 캐거나
    2. 모든 광물을 캔다.
  2. 한 곡괭이로 한번에 5개의 광물을 캐니,
    1. 광물 리스트를 최대 5개짜리의 섹션으로 나눈다
    2. 나눈 섹션의 각 광물의 갯수대로 최대의 피로도를 계산한다.
    3. 섹션 리스트에 모두 저장한다.
  3. 저장한 섹션 리스트를 피로드를 기준으로 내림차순 정렬한다.
  4. 내림차순으로 정렬한뒤 섹션을 효율 좋은 곡괭이를 먼저 사용한다.
    1. 각 곡괭이에 따른 피로도를 다시계산해서 결과에 더한다.
  5. 결과를 리턴한다.
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

int solution(vector<int> picks, vector<string> minerals) {
    int answer = 0;
    int n = minerals.size();
    int max_minerals = (picks[0] + picks[1] + picks[2]) * 5;
    if(n > max_minerals) n = max_minerals;
    vector<vector<int>> sections;
    for(int i = 0; i < n; i += 5)
    {
        int diamond = 0, iron = 0, stone = 0;
        for(int j = i; j < i + 5 && j < n; ++j)
        {
            if(minerals[j] == "diamond") diamond++;
            else if(minerals[j] == "iron") iron++;
            else stone++;    
        }
        int fatigue = diamond * 25 + iron * 5 + stone * 1;
        sections.push_back({diamond, iron, stone, fatigue});
    }
    
    sort(sections.begin(), sections.end(), [](const vector<int>& a, const vector<int>& b)
         {
             return a[3] > b[3];
         });
    
    for(auto& sec : sections)
    {
        if(picks[0] > 0)
        {
            answer += sec[0] * 1 + sec[1] * 1 + sec[2] * 1;
            picks[0]--;
        }
        else if(picks[1] > 0)
        {
            answer += sec[0] * 5 + sec[1] * 1 + sec[2] * 1;
            picks[1]--;
        }
        else if(picks[2] > 0)
        {
            answer += sec[0] * 25 + sec[1] * 5 + sec[2] * 1;
            picks[2]--;
        } else 
        {
            break;
        }
    }
    
    return answer;
}