https://school.programmers.co.kr/learn/courses/30/lessons/176962
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
문제 개요
과제들을 주어진 규칙에 따라 끝마친 순서부터 나열하는 문제이다.
여기서 아래 3가지 경우를 고려해야 한다.
i. 과제를 진행하는 중에 새 과제를 시작해야 하는 경우
ii. 한번에 과제를 다 끝낸 경우
iii. 모든 과제를 한번씩 진행하고, 못끝낸 과제가 남아있는 경우
알고리즘 및 풀이
1. plans 속 주어진 시간대를 분 단위로 통일한다.
def convert_time(s): # 시간을 분 단위로 변환
hh, mm = map(int, s.split(':'))
return hh * 60 + mm
def solution(plans):
ans = []
for i in range(len(plans)):
_, st, _ = plans[i]
st = convert_time(st)
plans[i][1] = st # 1. 시간대를 분 단위로 통일
plans[i][2] = int(plans[i][2]) # 소모시간은 정수로 변환
2. 일찍 시작하는 과제가 앞에 오도록 plans를 정렬한다.
# 2. 시작 시간 순서대로 정렬
plans.sort(key = lambda x:x[1])
stk = [] # 가장 최근에 들어온 과제부터 실행해야 하므로, LIFO인 스택 구조 활용
3. plans에 들어있는 과제들을 차례로 순회한다
# 3. 과제 순회
for i in range(len(plans)):
# 1) 마지막 과제라면
if i == len(plans) - 1:
stk.append(plans[i])
break
# 2) 현재 과제와, 바로 다음에 봐야 할 과제 정보 가져오기
task, st, dur = plans[i] # 현재 보는 과제
_, nex_st, _ = plans[i+1] # 다음에 봐야 할 과제
# 3) 다음 과제를 시작하기 전까지, 지금 보는 과제를 끝낼 수 있다면
if st + dur <= nex_st:
ans.append(task) # ans에 과제명 추가
temp_time = nex_st - (st + dur) # 다음 과제를 시작하기 전까지 남은 시간
while temp_time != 0 and stk: # 시간이 남았고, 아직 못 끝낸 과제들이 있다면
tmp_task, tmp_st, tmp_dur = stk.pop() # 가장 최근에 못끝낸 과제 정보
# (1) 시간이 남았고, 아직 못 끝낸 과제들이 있다면
if temp_time >= tmp_dur:
ans.append(tmp_task) # ans에 추가
temp_time -= tmp_dur # 남은 시간에서, 과제에 소모되는 시간만큼 차감
# (2) 다 끝내기엔 시간이 부족한 경우
else:
stk.append([tmp_task, tmp_st, tmp_dur - temp_time]) # 스택에 다시 넣기
temp_time = 0 # 남은 시간 초기화
# 4) 다음 과제를 시작하기 전까지, 현재 과제를 끝내지 못하면
else:
plans[i][2] = dur - (nex_st - st) # 현재 ~ 다음과제 시작하는 시간차만큼 소모시간 차감
stk.append(plans[i]) # 스택에 현재 과제 추가
1) 만약 지금 보는 과제가 마지막이라면, 이를 스택에 넣고 for-loop을 탈출한다.
2) 현재 보고있는 과제와, 바로 다음에 시작해야 하는 과제 별 정보를 가져온다.
3) 다음 과제를 시작하기 전까지 지금 보는 과제를 끝낼 수 있다면
(1) 지금 보는 과제를 ans에 추가한다.
(2) 남은 시간 동안, 스택의 맨 위에 남아있는 과제부터 처리한다.
4) 못끝낸다면, 다음 과제를 시작하기 전까지 현재 과제를 수행한다.
현재 시각과 새 과제를 시작하는 시각 사이의 시간차를 구하고, 이를 현재 과제의 소요 시간에서 차감한다.
4. 아직 스택에 남아있는 과제들을 맨 위에 남은 것부터 꺼내서, 이를 ans에 담는다.
# 4. 끝내지 못한 과제 처리
while stk:
task, _, _ = stk.pop() # 가장 먼저 끝내는 과제
ans.append(task) # ans에 추가
return ans
전체 코드
'''
- 문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/176962
- 참고 풀이: https://velog.io/@yeomja99/알고리즘-문제-풀이파이썬-프로그래머스-과제-진행하기
'''
def convert_time(s): # 시간을 분 단위로 변환
hh, mm = map(int, s.split(':'))
return hh * 60 + mm
def solution(plans):
ans = []
for i in range(len(plans)):
# 1. 시간대를 분 단위로 통일
_, st, _ = plans[i]
st = convert_time(st)
plans[i][1] = st # 1. 시간대를 분 단위로 통일
plans[i][2] = int(plans[i][2]) # 소모시간은 정수로 변환
# 2. 시작 시간 순서대로 정렬
plans.sort(key = lambda x:x[1])
stk = [] # 가장 최근에 들어온 과제부터 실행해야 하므로, LIFO인 스택 구조 활용
# 3. 과제 순회
for i in range(len(plans)):
# 1) 마지막 과제라면
if i == len(plans) - 1:
stk.append(plans[i])
break
# 2) 현재 과제와, 바로 다음에 봐야 할 과제 정보 가져오기
task, st, dur = plans[i] # 현재 보는 과제
_, nex_st, _ = plans[i+1] # 다음에 봐야 할 과제
# 3) 다음 과제를 시작하기 전까지, 지금 보는 과제를 끝낼 수 있다면
if st + dur <= nex_st:
ans.append(task) # ans에 과제명 추가
temp_time = nex_st - (st + dur) # 다음 과제를 시작하기 전까지 남은 시간
while temp_time != 0 and stk: # 시간이 남았고, 아직 못 끝낸 과제들이 있다면
tmp_task, tmp_st, tmp_dur = stk.pop() # 가장 최근에 못끝낸 과제 정보
# (1) 시간이 남았고, 아직 못 끝낸 과제들이 있다면
if temp_time >= tmp_dur:
ans.append(tmp_task) # ans에 추가
temp_time -= tmp_dur # 남은 시간에서, 과제에 소모되는 시간만큼 차감
# (2) 다 끝내기엔 시간이 부족한 경우
else:
stk.append([tmp_task, tmp_st, tmp_dur - temp_time]) # 스택에 다시 넣기
temp_time = 0 # 남은 시간 초기화
# 4) 다음 과제를 시작하기 전까지, 현재 과제를 끝내지 못하면
else:
plans[i][2] = dur - (nex_st - st) # 현재 ~ 다음과제 시작하는 시간차만큼 소모시간 차감
stk.append(plans[i]) # 스택에 현재 과제 추가
# 4. 끝내지 못한 과제 처리
while stk:
task, _, _ = stk.pop() # 가장 먼저 끝내는 과제
ans.append(task) # ans에 추가
return ans
제출 결과
'CodingTest' 카테고리의 다른 글
연속된 부분 수열의 합 (1) | 2024.03.27 |
---|---|
이웃한 칸 (1) | 2024.03.21 |
[PCCP 기출문제] 2번 / 석유 시추 (0) | 2024.03.05 |
[PCCP 기출문제] 1번 / 붕대 감기 (0) | 2024.03.04 |
[PCCE 모의고사] 10번 문제풀이 (0) | 2024.02.19 |