문제 링크 :https://school.programmers.co.kr/learn/courses/30/lessons/92341

주차 요금을 계산하려고 한다.
표의 흐름을 따라가보면
기본 시간은 180분, 기본요금 5,000원
그리고 180분이 지난 시간부터 10분마다 600원의 할증이 붙는 것 같다.
<차량들의 입,출차 기록이다.>
몇시 몇분에 어떤 차량이 입차했는지, 출차했는 지를 알려주고 있다.
< 주차요금 계산법과 몇가지 규칙들이 적혀있다.>
0000번 부터 보면 이 차는 위 입/출차 기록을 보면 6:00~6:34 주차하였고, 추가로 18:59 입차하여 출차 기록이 없다.
입차했는데 출차 기록이 없다면 당일 23:59에 출차한 것으로 간주한다고 규칙에 적혀있다.
그래서 0000은 34분 + 5시간 해서 총 334분 주차하였다.
주차 요금은 아까 예상한 것과 동일하게 매겨진다.
기본요금 + 초과한 시간당 단위시간당 요금으로.
단 초과한 시간이 단위시간으로 나누어 떨어지지 않으면, 올림한댄다.
즉 1분만 초과해도 단위시간으로 올라간다.
그래서 0000은 기본요금 5천원 + |(334- 기본시간 180) / 10|올림 x 600 = 14600 을 내야 한댄다.
친절하게 계산법까지 알려주었다.
계산법은
기본요금 +
(총 주차 시간 - 기본 시간) / 단위시간 을 올림한 값에
x 단위시간당 요금해주면 계산된다.
<입출력 예>

주차요금과 시간에 관련된 fees와 입/출차 관련 기록인 records가 주어진다.
fees 는 [기본 시간(분), 기본 요금(원), 단위 시간(분), 단위 요금(원] 배열로 주어진다.
records는 [입/출차 시간, 차량 번호, 입차인지 출차인지] 로 배열로 주어진다.
<제한사항>
제한 사항중 특이사항으로는
정도가 있는 것 같다.
결국에 입/출차 기록이 있는 차량들에 주차요금을 차량 번호가 작은 자동차부터 배열에 담아 return 하면 된다.
from collections import defaultdict
import math
def to_minutes(hhmm):
h, m = map(int, hhmm.split(':'))
return h * 60 + m
def solution(fees, records):
records_dict = defaultdict(list) # {차량번호 : [(입/출차 시간,IN or OUT), (입/출차 시간,IN or OUT)], 차량번호 : [ ... ] }
for r in records:
time, number, INorOUT = r.split(" ")
records_dict[number].append([time,INorOUT])
# records_dict = {'5961': [['05:34', 'IN'], ['07:59', 'OUT'], ['22:59', 'IN'], ['23:00', 'OUT']], '0000': [['06:00', 'IN'], ['06:34', 'OUT'], ['18:59', 'IN']], '0148': [['07:59', 'IN'], ['19:09', 'OUT']]})
# 내가 원하는 것, sorted_cars 순서대로 record_dict에 value들이 들어오는 것
sorted_cars_record = []
for k in sorted(records_dict):
sorted_cars_record.append(records_dict[k])
# sorted_cars_record = [[['06:00', 'IN'], ['06:34', 'OUT'], ['18:59', 'IN']], [['07:59', 'IN'], ['19:09', 'OUT']] , [['05:34', 'IN'], ['07:59', 'OUT'], ['22:59', 'IN'], ['23:00', 'OUT']]]
# IN만 있고 OUT이 없으면 ['23:59','OUT'] 을 추가 해주기
addition = ['23:59', 'OUT']
for record in sorted_cars_record:
if len(record) % 2 == 1:
record.append(addition)
# sorted_cars_record = [[['06:00', 'IN'], ['06:34', 'OUT'], ['18:59', 'IN'], ['23:59', 'OUT']], [['07:59', 'IN'], ['19:09', 'OUT']], [['05:34', 'IN'], ['07:59', 'OUT'], ['22:59', 'IN'], ['23:00', 'OUT']]]
result = []
for sorted_car_record in sorted_cars_record:
total_time = 0
for i in range(0,len(sorted_car_record), 2): # 쌍 마다 분 단위 차이를 누적.
tin, _ = sorted_car_record[i]
tout, _ = sorted_car_record[i+1]
total_time += to_minutes(tout) - to_minutes(tin)
if total_time <= fees[0]:
fee = fees[1] # 기본 요금이면 기본요금만
else:
over = total_time - fees[0]
units = math.ceil(over / fees[2])
fee = fees[1] + units * fees[3]
result.append(fee)
return result
for i in range(0,len(sorted_car_record), 2): # 쌍 마다 분 단위 차이를 누적.
이 기술이 이 문제의 포인트 중 하나였다.
i를 2씩 커지게 하여 한 쌍씩 가져와 out-in 을 할 수 있었다.
다음 날 다시 풀어보았다.
풀고나서 이전 풀이를 봤는데
for i in range(0,~~,2) 로 두 개씩 반복하는 기법을 쓰지 않고 풀었다.
IN에 모든 IN을 더하고 OUT에 모든 OUT을 다 더한뒤
OUT - IN 을 하여 총 시간을 구했다.
from collections import defaultdict
import math
# 문자열 hhmm = "03:30" -> 정수형 분 단위로 바꾸기 210
def time_to_minute(hhmm):
hh, mm = hhmm.split(":")
minute = int(hh) * 60 + int(mm)
return minute
# fees = [기본시간,기본요금,단위시간,단위시간당 요금] [180, 5000, 10, 600]
# records = ["05:34 5961 IN", "06:00 0000 IN", "06:34 0000 OUT", "07:59 5961 OUT", "07:59 0148 IN", "18:59 0000 IN", "19:09 0148 OUT", "22:59 5961 IN", "23:00 5961 OUT"]
def solution(fees,records):
# 내가 원하는 것
# 오름차순으로 정렬된 차량번호 리스트
# [ [ ] , [ ] , [ ] ] 이런식
records_dict = defaultdict(list)
for record in records: # record = "05:34 5972 IN"
time, number, INorOUT = record.split(" ")
records_dict[number].append([time,INorOUT])
sorted_car_records = []
for r in sorted(records_dict):
sorted_car_records.append(records_dict[r])
# sorted_car_records = [[['06:00', 'IN'], ['06:34', 'OUT'], ['18:59', 'IN']], [['07:59', 'IN'], ['19:09', 'OUT']], [['05:34', 'IN'], ['07:59', 'OUT'], ['22:59', 'IN'], ['23:00', 'OUT']]]
# 0000, 0148, 5961 순의 record들이 들어감
# IN,OUT이 홀수면 23:59 OUT 추가 해주기
for i in range(len(sorted_car_records)):
if len(sorted_car_records[i]) % 2 == 1:
sorted_car_records[i].append(["23:59", "OUT"])
answer = []
for sorted_car_record in sorted_car_records:
IN = 0
OUT = 0
for hhmm, INorOUT in sorted_car_record:
hhmm = time_to_minute(hhmm)
if INorOUT == "IN":
IN += hhmm
else:
OUT += hhmm
total = OUT - IN
fee = 0
# fees = [기본시간,기본요금,단위시간,단위시간당 요금] [180, 5000, 10, 600]
if total <= fees[0]: # total이 기본시간보다 안나왔을 때,
fee = fees[1] # 요금은 기본요금
else:
fee = fees[1] + math.ceil((total - fees[0]) / fees[2]) * fees[3]
answer.append(fee)
return answer