백준 2525번 풀이

문제

현재 시각에 분을 더했을 때 몇 시 몇 분인지 출력하는 문제. 알람시계 문제(2884번)와 비슷하지만 이 문제는 분이 고정값이 아니다.

풀이

내가 여기다 풀이를 올렸는지는 모르겠으나… 2884번 문제(알람시계)랑 비슷하다. 풀이를 보다 보면 알겠지만, 얘는 분이 고정값이 아니라 단식 if만 갖고는 처리 못 한다.

import sys
h,m = map(int, sys.stdin.readline().split())
spend = int(sys.stdin.readline())
print('{} {}'.format(h,m))

입력은 별 거 없고 걍 sys.stdin.readline() 줬다.

분이 59보다 클 때에 대한 처리

import sys
h,m = map(int, sys.stdin.readline().split())
spend = int(sys.stdin.readline())
m += spend
if m > 60:
  h += 1
  m -= 60
print('{} {}'.format(h,m))

이 문제의 조건문 분기 중 하나가 바로 분이 59보다 클 때에 대한 처리이다. 그럼 위 코드처럼 60 빼고 1 더하면 땡 아니냐고? 저거 저대로 내면 80분 90분 이렇게 더했을 때도 계산이 한 번만 된다. 조건문 자체는 뺑뺑이가 안 되기 때문. 다른 분들 풀이 보면 입력받은 분에 현재 시각의 분을 더해서 나누기 하시더라.

import sys
h,m = map(int, sys.stdin.readline().split())
spend = int(sys.stdin.readline())
m += spend
while True:
  m -= 60
  h += 1
  if m < 60:
    break
print('{} {}'.format(h,m))

계산까지는 모르겠고 걍 와일트루 줘버림. 아 상여자는 반복문이라고 참고로 저거 시간초과는 아니지만 아무튼 틀렸으므로 아직 내지 말자.

시간이 23보다 클 때

import sys
h,m = map(int, sys.stdin.readline().split())
spend = int(sys.stdin.readline())
m += spend
while True:
  m -= 60
  h += 1
  if m < 60:
    break
if h > 23:
  h -= 23
print('{} {}'.format(h,m))

시간은 걍 빼면 되는데, 저거 틀린 코드니까 아무튼 아직 내지 말자.

엥? 저게 왜 틀려요?

시간초과 때문은 아니고… 저 로직에서 크게 잘못된 두 가지는 와일트루와 시간 계산쪽이다. 그럼 반례를 하나씩 보면서 얘기해보자.

While True: 의 반례

14 30
20
15 -10

뭐가 잘못됐는지 바로 이해가 되시리라 생각된다. 두시 30분에서 20분이 지나면 두시 50분이 되어야 하는데, 그냥 60 빼고 1 더하고를 한 것이다. While True를 쓸 거면 while문 내부를 저 순서대로 하면 안 된다.

while m > 59:
  m -= 60
  h += 1

그래서 while에 조건이 붙어야 한다. 저게 시간초과로 틀린 게 아니라는게 상당히 의외다

시간 계산 반례

시간계산 반례는 쉽다. 23시 59분에 1분 더했는데 0시 0분이 아니라 1시 0분이 나온다. 시간이 23보다 클 때 23을 빼게 되어 있는데, 저렇게 되면 24-23=1, 24시가 새벽 1시가 된다. 그래서 23보다 클 때 24를 빼면 된다.

import sys
h,m = map(int, sys.stdin.readline().split())
spend = int(sys.stdin.readline())
m += spend
while m > 59:
  m -= 60
  h += 1
if h > 23:
  h -= 24
print(h,m)

그래서 최종적으로 이 코드가 맞다. 아까 While True가 순서가 틀렸다고 했는데

import sys
h,m = map(int, sys.stdin.readline().split())
spend = int(sys.stdin.readline())
m += spend
while True: 
  if m < 60:
    break
  m -= 60
  h += 1
if h > 23:
  h -= 24
print(h,m)

와일트루는 빠져나갈 조건문이 먼저 와야 한다. (안그러면 위에처럼 참사 터진다)