import re
def solution(lines):
answer = -1
start_sec_times = []
complete_sec_times = []
for line in lines:
k = line.split()
task = float(k[2][:-1])
h, m, s, ms = map(int, re.split('[^\w]', k[1]))
complete_sec_time = (3600 * h) + (60 * m) + s + (0.001 * ms)
start_sec_time = round(complete_sec_time - task + 0.001, 3)
complete_sec_times.append(complete_sec_time)
start_sec_times.append(start_sec_time)
for i in range(len(complete_sec_times)):
cnt = 1
for j in range(i + 1, len(start_sec_times)):
time = round(complete_sec_times[i] + 0.999, 3)
if time >= start_sec_times[j]:
cnt += 1
answer = max(cnt, answer)
return answer
시간/분/초/밀리초 단위를 초 단위로 변환하여 응답시작시간과 응답완료시간을 나타냈다.
# 예제3 예시
시작=75597.071 ~ 완료=75597.421, 처리시간(=T) = 0.351s
시작=75597.053 ~ 완료=75598.233, 처리시간(=T) = 1.181s
시작=75597.5 ~ 완료=75598.299
시작=75597.648 ~ 완료=75598.688
로그의 완료 시간과 시작 시간들을 비교하는 그리디적인 접근을 해야 최대값을 얻을 수 있다.예제2
에서 요구하는 대로 구간의 최대 처리량을 얻을 수 있다.
2중 for문을 사용하여 완료시간(i인덱스)과 그 다음 로그부터 마지막 로그까지의 시작시간(j인덱스)을 비교한다. 완료시간 + 0.999
보다 작거나 같은 시작시간들을 찾는다면 count+=1
해준다.
이 문제에서 0.001을 빼거나 0.009를 더할때 소수단위의 계산이 부정확하게 나오는 경우가 있다. 이를 방지하기 위해 반올림 함수인 round(숫자, 소수 n번째 자리까지 표현)
를 사용하여 값을 정확하게 수정했다.
# round 사용
3605.0009999999997 -> 3605.001
자주 사용하는 re.sub()
이나 re.split()
또한 확실하게 알아두자
# [a-zA-Z]: 모든 알파벳
# [\w]: 숫자와 알파벳
# [\d]: 숫자
# [\s]: 공백 단위
# ^: NOT
#+: 문자가 한 번 이상 존재
a = 'aA12*bcd/@p'
# [^\w]: NOT 숫자와 알파벳
b = re.split('[^\w]', a) # ['aA12', 'bcd', '', 'p']
# ([^\w])와 같이 ()로 묶어주면 나누는 기준이 되는 문자들이 사라지지 않는다.
c = re.split('([^\w])', a) # ['aA12', '*', 'bcd', '/', '', '@', 'p']
# +활용 예제: +는 [\d+]에서는 작동되지 않는다. [\d]+ 형태로 사용한다.
s = '200,300,400,22,2'
re.findall('[\d]', s) # ['2', '0', '0', '3', '0', '0', '4', '0', '0', '2', '2', '2']
re.findall('[\d]+', s) # ['200', '300', '400', '22', '2']
p = re.compile('(\d+)([SDT])([*#]?)')
dart = p.findall('1D2S3T*')
print(dart) # [('1', 'D', ''), ('2', 'S', ''), ('3', 'T', '*')]
# +: 1번 이상 사용
# re 는 아니지만 strip('.') -> 문장 앞 뒤 '.' 제거
before = '...aa.bb...c'
after = re.sub('[.]+', '.', before)
print(after) # .aa.bb.c