[프로그래머스] 과제 진행하기

Kim Yuhyeon·2023년 11월 7일
0

알고리즘 + 자료구조

목록 보기
153/161

문제

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

접근 방법

구현 문제
1. 00:00 ~ 23:59분으로 주어져 있는 문자열을 모두 계산하기 편하게 분으로 바꾼다.
2. 수행할 과제 idx와 현재 시간 currTime, 다음 과제를 시작할 시간 nextTime을 저장한다.
3. 반복문을 돌면서 과제를 수행한다.
<멈춰놓은 과제가 없을 때>

  • currTime <= nextTime 이라면 과제를 완료했으므로 answer에 넣는다.
  • 아니라면 멈춰놓은 과제 스택에 과목 이름, nextTime - currTime을 넣는다.
  • idx를 +1 한다.

<멈춰놓은 과제가 있을 때>

  • idxplans의 사이즈와 같은 경우 스택에 있는 것들을 순서대로 answer에 넣는다.
  • currTime < nextTime 인 경우 사이에 남은 시간이 있을 때이다.
    • 멈춰놨던 과제 스택에서 top을 꺼낸 후 시간을 비교해 완료했다면 pop , 완료하지 않았다면 남은 시간을 갱신한다.
    • currTime을 갱신한다.

풀이

#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#include <stack>

using namespace std;

// hhmm -> m
int timeToInt(string hhmm)
{
    return (60 * stoi(hhmm.substr(0, 2))) + stoi(hhmm.substr(3));
}

bool compare(vector<string> a, vector<string> b)
{
    return timeToInt(a[1]) < timeToInt(b[1]);
}

vector<string> solution(vector<vector<string>> plans) {
    vector<string> answer;
    stack<pair<string, int>> pauseSubjects;
    
    // 1. 과제 시작 시간 순대로 정렬 
    sort(plans.begin(), plans.end(), compare);
    
    int currTime = timeToInt(plans[0][1]);
    int nextTime = timeToInt(plans[1][1]);
    int idx = 0;

    while(idx < plans.size() || !pauseSubjects.empty())
    {
        // 멈춰놨던 과제 처리
        if (!pauseSubjects.empty())
        {
            // 마지막 순서 과제 처리가 끝났다면
            if (idx == plans.size())
            {
                answer.push_back(pauseSubjects.top().first);
                pauseSubjects.pop();
                continue; 
            }
            
            // 현재 시간이 다음 과제 실행 시간보다 작다면 
            if (currTime < nextTime)
            {
                // 남은 시간 동안 멈춰 놨던 과제 하기 

                int remainTime = pauseSubjects.top().second;
                int availableTime = nextTime - currTime;
                
                
                if (remainTime <= availableTime) // 과제 완료 
                {
                    answer.push_back(pauseSubjects.top().first);    
                    pauseSubjects.pop();
                    currTime += remainTime;
                }
                
                else // 과제 미완료
                {
                    pauseSubjects.top().second = remainTime - availableTime;
                    currTime = nextTime;
                }
                
                continue;
            }
        }
       
        // 다음 과제 처리 
        currTime = timeToInt(plans[idx][1]) + stoi(plans[idx][2]);
        nextTime = idx+1 >= plans.size()? 1440 : timeToInt(plans[idx+1][1]);

    
        if (currTime > nextTime) 
        {
            // 과제 중지 
            pauseSubjects.push({plans[idx][0], currTime - nextTime});
            currTime = nextTime;
        }
        else 
        { 
            // 과제 완료 
            answer.push_back(plans[idx][0]);    
        }
        
        ++idx; 
    }
    
       
    return answer;
}

정리

레벨 2라서 만만하게 봤다가 꼬박 2시간이 걸렸다..
아직 구현에 많이 약한 것 같아 많이 연습해야겠다.
코딩 테스트에 나왔으면 큰일났을 듯..

참고

https://beankong-devlog.tistory.com/120

0개의 댓글