[C++] BOJ 1308번: D-Day

ㅎㅎ·2023년 8월 30일
0

BOJ

목록 보기
44/65

BOJ 1308번: D-Day

문제


문제 풀이

어려운 문제가 아닌데 함정이 이곳저곳 있었다.

  1. 받은 두 날짜를 일 수로 변환해 저장한다.
  2. 뺄셈한 후 사이에 존재하는 윤년의 개수만큼 더해준다.
  3. 디데이가 1000년 이상이면 gg를 아니면 디데이를 출력한다.
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;

// 일수로 바꿔서 계산한 후 윤년이 있던 개수만큼 답에 증가한다.

struct date {
    int year;
    int month;
    int day;
};
int months[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

int leapyear(date d1, date d2) { // 윤년 개수 구하기
    int cnt = 0;
    if (d1.month > 2) { d1.year++; }
    if (d2.month > 2) { d2.year++; }
    for (int i = d1.year; i < d2.year; i++) {
        if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) { cnt++; }
    }
    return cnt;
}

int yeartoday(date d) { // 년월일을 일수로 바꾸기
    int date = 0;
    date += d.year * 365;
    for (int i = 0; i < d.month - 1; i++) { date += months[i]; }
    date += d.day;
    return date;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);

    date d, dday;
    int day1, day2, ans = 0;
    cin >> d.year >> d.month >> d.day;
    cin >> dday.year >> dday.month >> dday.day;

    day1 = yeartoday(d);
    day2 = yeartoday(dday);

    ans = day2 - day1;
    ans += leapyear(d, dday);

    if (ans >= 365243) { cout << "gg"; } // 1년은 365.2422일
    else { cout << "D-" << ans; }

    return 0;
}

윤년 조건문과 1000년에서 애를 먹었었다.

함정1. 윤년 구하기

윤년의 조건은 다음과 같다.

  • 서력기원 연수가 4로 나누어떨어지는 해는 우선 윤년으로 한다. (2004년, 2008년, …)
  • 100으로 나누어떨어지는 해는 평년으로 한다. (2100년, 2200년, …)
  • 400으로 나누어떨어지는 해는 다시 윤년으로 한다. (1600년, 2000년, …)

조건문을 만들 때 "4로 떨어져야하고.. 100으로는 떨어지면 안 되고.. 근데 400으로는 떨어져야 하고.." 하면서 아래와 같은 식을 만들게 되는데, 맞는 것 같지만 이 식은 틀렸다.

if (year % 4 == 0 && year % 100 != 0 && year % 400 == 0)

해당 조건문을 컴퓨터가 읽는 순서에서 이유를 알 수 있다. year가 100인 경우, 첫 번째 조건은 통과하지만 두 번째 AND 조건인 year % 100 != 0 에서 FALSE가 되어 다음 조건은 검사도 하지 않고 IF문을 나가버린다.

위의 3개의 조건을 다시 2개의 조건으로 정리할 수가 있는데,

  1. 4로 나누어떨어지면서 100으로 나누어떨어지지 않으면 윤년이다.
  2. 400으로 나누어떨어지는 해는 윤년이다.

위 조건을 조건문으로 만들면 아래와 같다.

if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)

이렇게 작성해야 윤년을 구할 수 있다.

함정2. 1000년은 며칠?

1년은 평균적으로 365.2422일이다.

1000년이라고 하면 단순하게 1000 * 365일 이라고 생각할 수 있지만, 정확한 1년은 365일이 아니라 365.2422일 이었다......

소수점 자리는 올림해서 1000년은 365243으로 계산한다.


profile
Backend

0개의 댓글