[BOJ 1308] - D-Day (구현, C++, Python)

보양쿠·2023년 7월 17일
0

BOJ

목록 보기
158/252

BOJ 1308 - D-Day 링크
(2023.07.17 기준 S5)

문제

오늘의 날짜와 D-Day인 날짜가 주어진다.
D-Day까지 1000년 이상이 남았으면 'gg', 아니면 남은 일수 출력

알고리즘

단순 구현

풀이

오늘부터 D-Day까지 하루씩 증가하면서 시뮬레이션 돌려도 되겠지만..?
그래도 좀 더 효율적으로 계산해보자.

D-Day - 오늘 = (1년 1월 1일 ~ D-day) - (1년 1월 1일 ~ 오늘) 이다.
그러니깐 오늘과 D-day의 총 일수를 구해 차이를 출력하면 된다.

총 일수를 구할 때 윤년이 좀 애매할 수 있다.
문제 지문에 나와 있듯이 조건의 우선순위를 높은 순으로 나열하면

  1. 400으로 나누어 떨어지면 무조건 윤년
  2. 100으로 나누어 떨어지지 않으며 4로 나누어 떨어지면 윤년

이를 조건식으로 그대로 나타내면 된다.


하지만 이 문제의 포인트는 윤년 계산뿐만 아니라, 1000년 이상 차이가 나는지 계산하는 것도 있다.

오늘 날짜인 2023년 7얼 17일과 3023년 1월 1일을 생각해보자. 연도는 딱 1000년 차이나지만 월이 넘지 않아 총 1000년 미만 차이가 나게 된다.
그렇다면 3023년 7월 1일은? 연도는 딱 1000년 차이, 월은 같지만, 일이 넘지 않아 총 1000년 미만 차이가 나게 된다.
그렇다면 3023년 7월 17일은? 연도는 딱 1000년 차이, 월과 일이 같아 정확하게 총 1000년 차이가 나게 된다.
그러니깐 요약하자면,

  • 연도가 1000년 초과 차이가 나거나
  • 연도가 1000년 차이가 나면서 월이 넘거나
  • 연도가 1000년 차이가 나면서 월은 같고 일이 같거나 넘어야 한다.
    이를 조건식으로 잘 나타내서 판별해보자.

코드

  • C++
#include <bits/stdc++.h>
using namespace std;

int days(int y, int m, int d){
    int result = 365 * (y - 1) + d - 1; // 지나온 연도 + 지나온 일수

    // 윤년은 하루 더한다.
    for (int i = 1; i < y; i++) if (!(i % 400) || (!(i % 4) && i % 100)) result++;

    // 지나온 월
    for (int i = 1; i < m; i++){
        if (i & 1 ^ (i >= 8)) // 홀수 달(8월부턴 짝수 달)은 31일
            result += 31;
        else if (i == 2){ // 2월
            if (!(y % 400) || (!(y % 4) && y % 100)) // 윤년이면 29일
                result += 29;
            else // 아니면 28일
                result += 28;
        }
        else // 나머지는 30일
            result += 30;
    }

    return result;
}

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

    int y1, m1, d1, y2, m2, d2;
    cin >> y1 >> m1 >> d1 >> y2 >> m2 >> d2;

    // 1000년 이상 차이가 나면 'gg' 출력
    if (y2 - y1 > 1000 || (y2 - y1 == 1000 && (m1 < m2 || (m1 == m2 && d1 <= d2))))
        cout << "gg";

    // 두 날짜의 일수 차이가 D-day가 된다.
    else cout << "D-" << days(y2, m2, d2) - days(y1, m1, d1);
}
  • Python
import sys; input = sys.stdin.readline

def days(y, m, d):
    result = 365 * (y - 1) + d - 1 # 지나온 연도 + 지나온 일수

    # 윤년은 하루 더한다.
    for i in range(1, y):
        if not i % 400 or (not i % 4 and i % 100):
            result += 1

    # 지나온 월
    for i in range(1, m):
        if i & 1 ^ (i >= 8): # 홀수 달(8월부턴 짝수 달)은 31일
            result += 31
        elif i == 2: # 2월
            if not y % 400 or (not y % 4 and y % 100): # 윤년이면 29일
                result += 29
            else: # 아니면 28일
                result += 28
        else: # 나머지는 30일
            result += 30

    return result

y1, m1, d1 = map(int, input().split())
y2, m2, d2 = map(int, input().split())

# 1000년 이상 차이가 나면 'gg' 출력
if y2 - y1 > 1000 or (y2 - y1 == 1000 and (m1 < m2 or (m1 == m2 and d1 <= d2))):
    print('gg')

# 두 날짜의 일수 차이가 D-day가 된다.
else:
    print('D-%d' % (days(y2, m2, d2) - days(y1, m1, d1)))
profile
GNU 16 statistics & computer science

0개의 댓글