2단계 문제 치고 상당히 복잡한 느낌이 들었다. 실제 코테에서 이런 문제가 나온다면 과감히 넘기는 편이 좋을거라는 생각도 들었다.
간단하게 문제를 요약하자면 시작 시간을 기준으로 과제를 수행하다가 다른 과제를 시작해야하면 대기 스택에 하던 과제를 넣어놓고 주어진 과제를 수행하고, 만약 남는 시간이 생기면 대기 스택에서 가져와 과제를 수행한다 생각하면 된다.
#include <string>
#include <vector>
#include <deque>
#include <algorithm>
using namespace std;
bool compare(tuple<string,int,int>a, tuple<string,int,int>b)
{
return get<1>(a) < get<1>(b);
}
int after_study(int start, int time)
{//start + time을 반환 => 1200 부터 70 분 공부하면 1310 반환
int start_h = start/100, start_m = start%100;
int time_h = time/60, time_m = time%60;
return ((start_h + time_h + (start_m + time_m)/60)*100 + (start_m + time_m)%60);
}
int rest_time(tuple<string,int,int> cur, tuple<string,int,int> start, int time)
{//과제를 수행한 시간을 해당 과제 총 공부시간에서 빼준다.
int h,m;
h = get<1>(start) / 100 - time / 100;
m = get<1>(start) % 100 - time % 100;
time = h * 60 + m;
return (get<2>(cur) - time);
}
vector<string> solution(vector<vector<string>> plans)
{
int n = plans.size();
vector<string> answer;
deque<tuple<string,int,int>> list, wait;
for(int i=0;i<n;i++) list.push_back({plans[i][0], stoi(plans[i][1]) * 100 + stoi(plans[i][1].substr(3,2)), stoi(plans[i][2])});
// list에 stoi해줘서 넣어준다.
sort(list.begin(),list.end(),compare);//시작시간순으로 정렬
int time = get<1>(list.front());// 현재 시간
while (!list.empty() || !wait.empty())//과제가 남아있다면
{
tuple<string,int,int> cur;
if (!wait.empty() && (list.empty() || time < get<1>(list.front())))
{// 대기중 && 현재 시간 < 다음 공부 시작 시간
cur = wait.front();
wait.pop_front();
}
else
{// 대기중인게 없거나 현재시간이 시작해야하는 과제시간 일때
cur = list.front();
list.pop_front();
time = get<1>(cur);//현재시간 갱신
}
if (!list.empty() && after_study(time, get<2>(cur)) > get<1>(list.front()))
{//현재 과제가 다음 과제 시작 시간보다 늦게 끝나면
get<2>(cur) = rest_time(cur, list.front(), time);
wait.push_front(cur);
time = get<1>(list.front());
}
else
{// 그전에 끝나면
answer.push_back(get<0>(cur));
time = after_study(time, get<2>(cur));
}
}
return answer;
}