시계 문제는 시 : 분 : 초로 입력값이 주어질 때 혹은 비슷한 입력값으로 주어질 때 문제를 어떻게 풀어야 하는지 설명하는 글입니다.
풀이 방법은 크게 2가지로 나뉘는데 하나는 시, 분, 초 값을 그대로 이용해서 시뮬레이션을 돌리는 방법이고, 하나는 1시간 = 60분 = 3600초, 1분 = 60초로 전부 초 단위로 값을 변경한 후에 문제를 해결하는 방법입니다.
보통 이런 문제는 후자가 푸는 방법이 쉽기 때문에 초 단위로 변경해서 문제를 많이 풀고, 후자로 문제를 풀 수 없는 경우에는 전자로 문제를 풀고 있습니다. 문제 2개를 풀어보면서 어떻게 코드를 짜야 할지 알아봅시다.
1. 시뮬레이션 - BOJ 1942
각 줄마다 hh:mm:ss hh:mm:ss 를 총 3줄 동안 입력을 받아서 3의 배수의 개수를 출력하는 문제입니다.
일단 입력 값은 6개의 시간으로 나누어주어야 하고, 각각 6개의 변수에 시, 분, 초를 저장해주어야 합니다.
그러면 먼저 공백을 기준으로 문자열을 나누어주고, 그다음 콜론(':')을 기준으로 (시):(분):(초)를 나누어주면 됩니다.
for i inrange(3): a, b =input().split() h1, m1, s1 =map(int, a.split(':')) h2, m2, s2 =map(int, b.split(':')) blah blah
그리고 이제 시계가 돌아가는데 시계에 나온 정수가 3의 배수인 것의 개수를 구해줍니다. 먼저 개수를 구해줘야 하니까 3의 배수가 나올 때마다 값을 더해줄 변수가 필요하겠네요. for문이 돌아가는 동안 값을 계속 저장해나가면서 진행해야 하므로 ans라는 변수를 추가합니다.
for i inrange(3): a, b =input().split() h1, m1, s1 =map(int, a.split(':')) h2, m2, s2 =map(int, b.split(':')) ans =0 blah blah
이제 h1:m1:s1 ~ h2:m2:s2 시간동안 3의 배수 정수가 몇 개인지 for문 또는 while문을 이용하여 문제를 풀어줍니다. 저는 while문을 이용하여 풀어보겠습니다.
while문의 조건은 h, m, s의 값들이 서로 같지 않을 때까지 돌리면 됩니다.
for i inrange(3): a, b =input().split() h1, m1, s1 =map(int, a.split(':')) h2, m2, s2 =map(int, b.split(':')) ans =0while1:if (h1 == h2) and (m1 == m2) and (s1 == s2):break
이제 s1에 계속 1을 더해주면서 s1이 60이 되면 m1의 값을 1 더해주고, m1의 값이 60이 되면 h1의 값을 올려주면 됩니다. 그리고 h1의 값이 24가 되면 0으로 바꾸어야 합니다.
for i inrange(3): a, b =input().split() h1, m1, s1 =map(int, a.split(':')) h2, m2, s2 =map(int, b.split(':')) ans =0while1:if s1 ==60: m1 +=1; s1 =0if m1 ==60: h1 +=1; m1 =0if h1 ==24: h1 =0if (h1 == h2) and (m1 == m2) and (s1 == s2):break s1 +=1
s1의 위치가 왜 맨 아래에 있냐면 while문 첫 줄에 s1+=1을 넣어주면 처음 시간은 통과하게 되고, break문 위에 s1 += 1을 넣어주면 h2, m2, s2일 때의 시간을 포함하지 않고 계산하게 됩니다.
그리고 이제 3의 배수임을 확인해야 하는데, 이건 수식을 이용하든 str형으로 변환해서 다 합친 다음 int형으로 만들어주든 맘에 드는 것을 하나 골라서 하시면 됩니다.
저는 수식을 이용하여 만들겠습니다. 해당 수식이 3으로 나누어 떨어지면 ans에 1을 더해주면 됩니다.
for i inrange(3): a, b =input().split() h1, m1, s1 =map(int, a.split(':')) h2, m2, s2 =map(int, b.split(':')) ans =0while (h1 != h2) or (m1 != m2) or (s1 != s2):if s1 ==60: m1 +=1; s1 =0if m1 ==60: h1 +=1; m1 =0if h1 ==24: h1 =0 x = h1 *10000+ m1 *100+ s1if x %3==0: ans +=1if (h1 == h2) and (m1 == m2) and (s1 == s2):break s1 +=1
그리고 이제 while문을 탈출하고 ans를 출력해주면 됩니다.
for i inrange(3): a, b =input().split() h1, m1, s1 =map(int, a.split(':')) h2, m2, s2 =map(int, b.split(':')) ans =0while (h1 != h2) or (m1 != m2) or (s1 != s2):if s1 ==60: m1 +=1; s1 =0if m1 ==60: h1 +=1; m1 =0if h1 ==24: h1 =0 x = h1 *10000+ m1 *100+ s1if x %3==0: ans +=1if (h1 == h2) and (m1 == m2) and (s1 == s2):break s1 +=1print(ans)
2. 초 단위로 전부 변경 - BOJ 2530
시 분 초가 주어지고, 요리하는데 필요한 시간이 주어진다고 합니다.
일단 입력값을 받아봅시다.
a, b, c =map(int,input().split())d =int(input())
이번에는 전부 초 단위로 변경하여 풀기로 하였으니 x라는 변수에 3600*a + 60*b + c를 저장합니다.
a, b, c =map(int,input().split())d =int(input())x =3600* a +60* b + c
그리고 우리는 오븐구이가 끝나는 시각을 출력해야 하므로 d도 더해주면 됩니다.
a, b, c =map(int,input().split())d =int(input())x =3600* a +60* b + c + d
이제 출력을 할 때는 x를 3600으로 나눈 몫이 시가 되겠습니다.
a, b, c =map(int,input().split())d =int(input())x =3600* a +60* b + c + dh = x //3600
그리고 분은 x를 3600으로 나눈 나머지에서 60으로 나눈 몫이 됩니다.
a, b, c =map(int,input().split())d =int(input())x =3600* a +60* b + c + dh = x //3600m = (x %3600) //60
마지막으로 초는 x를 3600으로 나눈 나머지에 60을 나눈 나머지를 구하면 됩니다.
a, b, c =map(int,input().split())d =int(input())x =3600* a +60* b + c + dh = x //3600m = (x %3600) //60s = (x %3600) %60
이제 출력을 하면 됩니다.
a, b, c =map(int,input().split())d =int(input())x =3600* a +60* b + c + dh = x //3600m = (x %3600) //60s = (x %3600) %60print(h, m, s)