문제

도현이는 Counter Terror Unit (CTU)에서 일하는 특수요원이다. 도현이는 모든 사건을 정확하게 24시간이 되는 순간 해결하는 것으로 유명하다. 도현이는 1시간 만에 범인을 잡을 수 있어도 잡지 않는다. 정확하게 24시간이 되는 순간이 아니면 잡지 않는 CTU 특수요원이다.

2008년 3월 3일 월요일, CTU는 새학기에 맞춰 핵폭탄을 날리겠다는 테러 정보를 입수했다. CTU에서는 특수요원 도현이에게 이 임무를 맡겼다. CTU의 프로그래머 준규는 이 사건의 배후가 김선영이란 것을 해킹을 통해 밝혀내었다.

도현이는 선영이를 임무를 시작한지 정확하게 24시간이 되는 순간에 잡으려고 한다.

만약 지금 시간이 13:52:30이고, 임무를 시작한 시간이 14:00:00 이라면 도현이에게 남은시간은 00:07:30 이다.

모든 시간은 00:00:00 ~ 23:59:59로 표현할 수 있다. 입력과 출력에 주어지는 모든 시간은 XX:XX:XX 형태이며, 숫자가 2자리가 아닐 경우에는 0으로 채운다.

도현이가 임무를 시작한 시간과, 현재 시간이 주어졌을 때, 도현이에게 남은 시간을 구하는 프로그램을 작성하시오.

  • 입력
    • 첫째 줄에는 현재 시간이, 둘째 줄에는 도현이가 임무를 시작한 시간이 주어진다. 임무를 시작한 시간과 현재 시간이 같은 경우는 주어지지 않는다.
  • 출력
    • 첫째 줄에 도현이가 임무를 수행하는데 남은 시간을 문제에서 주어지는 시간의 형태 (XX:XX:XX)에 맞춰 출력한다.

코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
using namespace std;

int getSecond(int h, int m, int s){
    int sum = 0;

    sum += h * 3600;
    sum += m * 60;
    sum += s;

    return sum;
}

void getTime(int sec, int &h, int &m, int &s){
    h = sec / 3600;
    m = (sec % 3600) / 60;
    s = (sec % 3600) % 60;
}

int main(void){
    int now_h, now_m, now_s;
    int start_h, start_m, start_s;

    scanf("%d:%d:%d", &now_h, &now_m, &now_s);
    scanf("%d:%d:%d", &start_h, &start_m, &start_s);

    int nowSecond = getSecond(now_h, now_m, now_s);
    int startSecond = getSecond(start_h, start_m, start_s);

    int resTime = startSecond - nowSecond;
    if (resTime < 0){
        start_h += 24;
        startSecond = getSecond(start_h, start_m, start_s);
        resTime = startSecond - nowSecond;
    }

    int res_h = 0, res_m = 0, res_s = 0;

    getTime(resTime, res_h, res_m, res_s);

    printf("%02d:%02d:%02d\n", res_h, res_m, res_s);

    return 0;
}

접근 및 풀이

입력을 여러가지로 생각해 보아야 하는 문제였다. 나는 입력받은 시간을 모두 초로 환산하여 계산하는 방법을 사용하였지만, 그렇게 하지 않고 하드코딩 하는 방법도 있는 듯했다. 아무래도 초로 환산하여 사용하는 것이 가장 효율적인 방법이 아닐까 싶다.

가장 기본적인 입력은 예제에 나와있는 13:52:30 ~ 14:00:00 일 것인데, 이 경우는 남은 시간 계산이 뚜렷하게 보이기 때문에 통과되었지만 문제는 뒤에 나올 반례들이었다. 먼저 원래 짠 코드에서는 임무 시작 시간이 00:00:00일 경우를 생각하지 못했다. 임무 시작 시간이 00:00:00일 경우는 환산하면 0초가 나오기 때문에 계산을 제대로 할 수 없었다. 이는 24:00:00과도 같은 경우이기 때문에 임무 시작 시간 부분이 00이면 24로 바꾸도록 조건을 추가하였는데, 이건 잘못된 것이었다. 14:00:00 ~ 13:52:30와 같이 임무 시작 시간이 더 뒤일 경우 모두를 생각했어야 했다. 그래서 기본적으로는 임무 시작 시간을 초로 환산했을 때 더 크다고 가정하고 계산하도록 하였으니 만약 계산 후 음수가 나온다면 24h를 더해서 다시 계산하도록 하였다.

그리고 원래는 cin이나 cout을 자주 써주었지만 이번같이 형식이 주어진 입출력에는 쓰는게 형식지정자를 써주는 함수들을 맞다고 생각해 printfscanf를 써주었다.

댓글남기기