{}연습장
대시보드학습스킬 경로문제모의고사라이브 코테복습데이터
문제 목록〉시뮬레이션〉킥보드 심야 요율 정산← 이전다음 →
#110 · 시뮬레이션중간이벤트 로그,해시,구간별 요율

킥보드 심야 요율 정산

문제

공유 킥보드 서비스의 하루치 운행 로그로 가장 많은 요금을 낸 사용자 를 찾으려 합니다.

요금 정책 policy = [base, dayRate, nightRate, pickupFee]는 다음과 같습니다.

  • base: 대여 1건마다 붙는 기본요금
  • dayRate: 주간 1분당 요금 — 주간은 06:00 이상 22:00 미만입니다
  • nightRate: 심야 1분당 요금 — 심야는 00:0005:59와 22:0023:59입니다
  • pickupFee: 운영 종료 시각까지 반납되지 않아 회수한 대여 1건마다 붙는 회수 수수료

요금은 1분 구간 단위 로 계산합니다. 어떤 1분 구간의 시작 시각 이 주간에 속하면 그 1분은 dayRate, 심야에 속하면 nightRate로 계산합니다. 예를 들어 05:58에 빌려 06:02에 반납했다면 심야 2분 + 주간 2분입니다.

운행 로그 logs의 각 원소는 다음 두 형식 중 하나이며, 시각 오름차순으로 주어집니다. 같은 시각의 이벤트가 여러 개면 주어진 순서대로 처리합니다.

형식 의미
"HH:MM|사용자ID|OUT" 그 시각에 킥보드를 빌렸다
"HH:MM|사용자ID|IN" 그 시각에 킥보드를 반납했다

운영 종료 시각 closeTime("HH:MM")까지 반납 기록이 없는 대여는 closeTime에 회수한 것으로 보고, 그 시각까지의 요금에 pickupFee를 더합니다. 한 사용자가 하루에 여러 번 빌릴 수 있으며(반납한 시각에 곧바로 다시 빌릴 수도 있습니다), 그때는 대여 건마다 기본요금을 포함해 계산한 뒤 합산합니다.

총 지불액이 가장 큰 사용자의 [사용자ID, 총액]을 반환하는 solution(policy, closeTime, logs) 함수를 작성하세요. 총액이 같은 사용자가 여럿이면 사용자ID가 사전순으로 앞선 사용자를 반환합니다.

예시

policy=[400, 120, 200, 5000], closeTime="23:30"
logs=["07:00|rin|OUT", "07:20|rin|IN", "21:50|dax|OUT", "22:20|dax|IN"]
→ ["dax", 5600]
  rin: 주간 20분 → 400 + 20×120 = 2800
  dax: 주간 10분(21:50~21:59) + 심야 20분(22:00~22:19)
       → 400 + 10×120 + 20×200 = 5600
 
policy=[400, 120, 200, 5000], closeTime="23:30"
logs=["09:00|dax|OUT", "09:30|dax|IN", "23:00|rin|OUT"]
→ ["rin", 11400]
  dax: 주간 30분 → 400 + 3600 = 4000
  rin: 미반납 → 23:30까지 심야 30분 → 400 + 6000 = 6400, 회수 수수료 5000 추가
 
policy=[1000, 50, 50, 3000], closeTime="22:00"
logs=["10:00|zoe|OUT", "10:20|zoe|IN", "11:00|ann|OUT", "11:20|ann|IN"]
→ ["ann", 2000]
  둘 다 1000 + 20×50 = 2000으로 같으므로 사전순 앞선 ann

제약 조건

  • policy.length = 4, 각 값은 0 이상 100,000 이하의 정수
  • 1 ≤ logs.length ≤ 1,000
  • 모든 시각은 00:00~23:59의 24시간제 HH:MM 형식이며, 로그의 시각은 closeTime 이하입니다
  • 사용자ID는 영소문자·숫자 1~10자
  • 로그는 항상 유효합니다 — 대여 중이 아닌 사용자만 OUT, 대여 중인 사용자만 IN이 나옵니다
  • OUT 이벤트가 최소 1건 있습니다

시간 복잡도 목표: O(N) (N = logs.length)

테스트 케이스

예시 1: 주간 이용과 심야 걸침 비교
입력: policy = [400,120,200,5000], closeTime = "23:30", logs = ["07:00|rin|OUT","07:20|rin|IN","21:50|dax|OUT","22:20|dax|IN"]
출력: ["dax",5600]
예시 2: 미반납 → 운영 종료 시각 정산 + 회수 수수료
입력: policy = [400,120,200,5000], closeTime = "23:30", logs = ["09:00|dax|OUT","09:30|dax|IN","23:00|rin|OUT"]
출력: ["rin",11400]
예시 3: 총액 동점 → 사용자ID 사전순
입력: policy = [1000,50,50,3000], closeTime = "22:00", logs = ["10:00|zoe|OUT","10:20|zoe|IN","11:00|ann|OUT","11:20|ann|IN"]
출력: ["ann",2000]
같은 사용자의 여러 건은 건별 기본요금 후 합산
입력: policy = [300,100,150,2000], closeTime = "23:00", logs = ["06:00|kai|OUT","06:10|kai|IN","06:10|kai|OUT","06:40|kai|IN"]
출력: ["kai",4600]
엣지: 이용 0분도 기본요금은 부과
입력: policy = [300,100,150,2000], closeTime = "20:00", logs = ["12:00|pip|OUT","12:00|pip|IN","12:05|quo|OUT","12:06|quo|IN"]
출력: ["quo",400]
경계: 자정 대여 → 06:00에 요율이 바뀜
입력: policy = [500,10,90,7000], closeTime = "23:59", logs = ["00:00|nox|OUT","06:30|nox|IN"]
출력: ["nox",33200]
solution.ts
에디터 로딩 중…

▶ 실행은 기록 없이 채점만, 제출은 결과가 진행률·오답노트에 기록됩니다.