알고리즘/프로그래머스 2단계

프로그래머스 - 기능 개발 - C++

게임만드는학생 2024. 7. 31. 12:54

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

 

프로그래머스

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

programmers.co.kr

 

#include <string>
#include <vector>

using namespace std;

vector<int> solution(vector<int> progresses, vector<int> speeds) {
    vector<int> answer;
    int num=0;
    int size = progresses.size();
    while(num<size)
    {
        if(progresses[num]<100)
        {
            for(int i=num;i<size;i++)
                progresses[i]+=speeds[i];
        }
        else
        {
            int cnt=0;
            for(int i=num;i<size;i++)
            {
                if(progresses[i]>=100)
                {
                    num++;
                    cnt++;
                }
                else
                {
                    num=i;
                    break;
                }
            }
            answer.push_back(cnt);
        }
    }
    
    return answer;
}


하루를 기준으로 작업량이 100% 가 되면 배포를 진행한다.

하루마다 배포되는 수를 리턴하는 문제이다.

 

우선순위를 기준으로 현재 작업도가 progresses 에 주어지고, 하루마다 진척되는 양이 speeds에 주어진다. 

더 높은 우선순위가 배포되지 않으면 배포할 수 없다.

 

주어진 progresses 벡터를 이용해 배포된 수는 num에 저장하여 while문을 돌렸다.

while 반복한번마다 하루가 지난다. 

그 안에서 num은 가장 앞순위의 인덱스를 뜻하기도 한다. 

따라서 progresses[num] 이 진행도 100% 라면 그 뒤에 완료된 것이 있는지 확인하고 그 수를 세어 answer에 저장한다.

만약 그렇지 않다면 num부터 그 뒤 모든 작업의 작업을 시작한다. 

 

 

위의 풀이는 모든 작업을 for문을 통해 직접진행하며 완료도를 비교했지만

수식으로 남은 날을 계산하여 더 간단하게 풀이할 수 있다.

 

#include <string>
#include <vector>

using namespace std;

vector<int> solution(vector<int> progresses, vector<int> speeds) {
    vector<int> answer;
    
    int max_day=0;
    
    for(int i=0;i<progresses.size();i++)
    {
        // 100 일 때는 나머지가 0인지 아닌지에 따라 나누지만 99로 하면 무조건 +1을
        // 해야함
        // day는 현재 작업이 완료되기까지의 일 수
        int day = (99-progresses[i]) / speeds[i] + 1;    
        
        // 빈 경우는 맨처음, max_day는 지금 이 작업이 배포되려면 며칠을 기다려야하는지
        if(answer.empty() || max_day < day)
            answer.push_back(1);
        else
        // max_day보다 day가 작으면 이미 작업이 완료된 상태이기 때문에 배포수 + 1
            answer.back()++;
        
        // day가 더 크면 이전까지의 작업은 다 배포완료되었고 지금 i번째 작업이 완료되기를
        // 기다려야한다.
        if(max_day<day)
            max_day = day;
    }
    
    return answer;
}

 

우선순위대로 벡터에 작업이 주어졌으니 for문으로 i 를 0부터 뒤로 시작하면 된다. 

day에 이 작업이 완료되려면 얼마나 걸리는지를 나타내고 max_day보다 day크면 

answer에 1을 추가한다. 

max_day는 이 작업의 완료여부를 떠나서 앞 순위의 작업을 기다려야하는 일 수를나타낸다. 

그것보다 나의 작업이 더 오래걸리면 이후에 배포될 것이기 때문에 1을 추가하는 것이다. 

 

day가 더 작은 경우는 이미 max_day가 되기전에 작업이 완료되고 앞 우선순위의 작업완료를 기다린 상태이다.

따라서 바로 배포를 같이할 수 있기 때문에 가장 마지막 배포와 동일한 날에 배포가 가능하다.

따라서 back()에 1을 더한다. 

 

마지막으로 max_day보다 day가 크면 새로 max_day를 갱신해서 뒤에 몇일이 걸리는지를 알린다.

 

처음에 남은 일 수를 계산한 것을 이용하면 어떻게 되겠다하는 생각이 들었지만 복잡해질것 같기도 하고 잘 떠오르지 않아 더 익숙한 방법을 택한 것 같다. 종이에 적으면서 했으면 괜찮았을 것 같기도하다.