관리 메뉴

Bull

[백준] 1408: 24 (C++) 본문

Algorithm/Baekjoon

[백준] 1408: 24 (C++)

Bull_ 2024. 1. 28. 06:36

https://www.acmicpc.net/problem/1408

 

1408번: 24

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

www.acmicpc.net

 

 

 

 

요구사항

① 두 시간을 입력 받는다 (00:00:00형식)

② 첫 시간과 2번째 시간의 차를 구한다.

 


주의사항

① 여기서 첫째 시간보다 둘째 시간이 더 크다는 조건이 따로 붙어있지 않다.

 

 

 

코드

#include <iostream>
#include <vector>
using namespace std;

int time2sec(string str) {
    int sum = 0;
    sum += stoi(str.substr(0, 2)) * 3600; 
    sum += stoi(str.substr(3, 2)) * 60;   
    sum += stoi(str.substr(6, 2));        
    return sum;
}

vector<int> sec2time(int sec) {
    vector<int> time;
    time.push_back(sec / 3600);         
    sec %= 3600;
    time.push_back(sec / 60);           
    sec %= 60;
    time.push_back(sec);           
    return time;
}


void print_time(vector<int> time) {
    for (int i = 0; i < 3; i++) {
        cout.width(2);
        cout.fill('0');
        cout << time.at(i);
        if (i < 2) cout << ":";
    }
}

int main() {
    string a, b;
    vector<int> time;
    int r_time;
    cin >> a >> b;
    r_time = time2sec(b) - time2sec(a);
    if (r_time < 0) {
        r_time += 24 * 3600;
    }
    time = sec2time(r_time);
    print_time(time);   
    return 0;
}

 

 

 

 

 

 

1. 변환 (초 단위)
int time2sec(string str) {
    int sum = 0;
    sum += stoi(str.substr(0, 2)) * 3600; 
    sum += stoi(str.substr(3, 2)) * 60;   
    sum += stoi(str.substr(6, 2));        
    return sum;
}

 

우선 두 개의 시간의 차를 구하기 위해 초 단위로 변환하여 차를 구한다.

 

 

 

 

 

2. 차 구하기
int main() {
.
.
.
    r_time = time2sec(b) - time2sec(a);
    if (r_time < 0) {
        r_time += 24 * 3600;
    }
.
.
.
}

초 단위인 남은시간(remain_time) 변수에 두 수를 뺀 값을 넣는데

 

첫째 줄에는 현재 시간이, 둘째 줄에는 임무를 시작한 시간이 주어질 때

 

현재시간 17:00:00
임무를 시작한 시간 12:00:00


처럼 다음날일 경우 (둘째 줄 시간 - 첫째 줄 시간)은 음수가 되므로

 

24시간의 초단위에서 음수의 결과를 더해주면 된다.(결론적으론 빼기)

 

 

 

 

 

3. 변환(주어진 형식)

 

vector<int> sec2time(int sec) {
    vector<int> time;
    time.push_back(sec / 3600);         
    sec %= 3600;
    time.push_back(sec / 60);           
    sec %= 60;
    time.push_back(sec);           
    return time;
}

time 벡터에 시, 분, 초 단위로 숫자를 변환하여 저장했다.

 

주어진 예제를 넣으면 time = [0, 7, 30]이 된다.

 

 

 

 

 

 

 

4. 출력
void print_time(vector<int> time) {
    for (int i = 0; i < 3; i++) {
        cout.width(2);
        cout.fill('0');
        cout << time.at(i);
        if (i < 2) cout << ":";
    }
}

형식의 각 자리에서 시간이 일의 자리라면 십의 자리는 0으로 채워야 한다.

 

위와 같이 cout.width(2)로 2자리수의 넓이를 확보하고 빈 공간은 cout.fill('0')을 통해 00으로 채워준다.

 

00:07:30

으로 정상적인 출력이 된다.

 

 

 

 

 

여담

time2sec(), sec2time() 함수를 for문으로 작성을 하려했지만 끽해야 2번의 반복연산이기 때문에 직관적으로 보는 게 낫다고 판단했다.

 

for이 들어간 코드를 짜다가 for문의 인자 i를 응용해(substr, 60제곱 등) 시간 단위를 바꾸는 과정에서 헷갈려서 여러번 번복하였다.

 

또한 C++은 pow(double, double)이어서 1정도의 오차도 발생했다.

 

제곱 연산자도 이상하게 연산이 제대로 되지 않았다.

 

그래서 custom_pow()를 만들던 중, 적은 연산이므로  for문을 사용하기 보단 일반적으로 적는게 함수도 적게 들고 연산의 복잡성도 줄어들 거 같단 생각을 했다.

'Algorithm > Baekjoon' 카테고리의 다른 글

[백준] 10830: 행렬 제곱 (C++)  (0) 2024.04.04
[백준] 2581: 소수 (C++)  (1) 2024.02.24
[백준] 5565: 영수증 (C++)  (0) 2024.01.26
[백준] 10984: 내 학점을 구해줘 (C++)  (1) 2024.01.25
[백준] 2822: 점수 계산 (C++)  (1) 2024.01.23