[BOJ 9428] Effective Infection Time

BOJ 9428번 문제 정보

  • 해결 일자 : 2023년 6월 30일
  • solved.ac 난이도 : Bronze III (해결일 기준)

BOJ 9428번 문제 번역 (영어)

감염에 방치된 격리 구역의 위협 수준을 추정하고 있습니다. 영역의 위협 수준을 결정하는 주요 변수 중 하나는 EIT(Effective Infection Time)입니다. 이 정보는 격리된 지역을 되찾기 위한 증상 발생 날짜를 계획하는 데 필수적입니다. EIT는 다음 규칙에 따라 계산됩니다.

  • EIT는 감염 날짜(Infection Date)와 증상 발생 날짜(Strike Date)의 함수 결과입니다.
  • 모든 연도는 A.Z.(After Zombie)에 포함됩니다.
  • 매월 마지막 날이 지난 후 EIT의 일부로 계산됩니다. 따라서, 증상 발생 날짜가 속한 달은 EIT에 속하지 않습니다.
  • 감염이 발생한 첫해는 1/2 EIT로 계산됩니다.
    • 연말에 도달하지 않았으면 매월은 1/2 EIT의 일부만 계산됩니다.
      • 만약 영역이 첫 해 1월에 감염됐다면 1/2 EIT는 12개월에 걸쳐 분산됩니다((1/2)/12 = 월별 약 0.0417 EIT).
      • 만약 영역이 첫해 3월에 감염됐다면 1/2 EIT는 10개월에 걸쳐 분산됩니다((1/2)/10 = 월별 0.0500 EIT).
    • 연말에 도달하면 감염 월에 상관없이 해당 연도는 전체 1/2 EIT로 계산됩니다. 예를 들어 15 AZ의 2월에 감염된 영역은 15 AZ 12월 이후 1/2 EIT로 계산됩니다. 같은 해 12월에 감염된 영역도 1/2 EIT로 계산됩니다.
  • 이후의 모든 연도는 1 EIT로 계산됩니다. 1월부터 시작하여 매월 1/12 EIT(약 0.0833 EIT)로 계산됩니다.
  • 같은 달에 감염된 모든 영역은 특정한 증상 발생 날짜에 대해 같은 EIT를 갖습니다. 따라서 월과 연도만 제공됩니다.

달력 연도의 월 수와 순서는 현대 그레고리력과 동일하게 유지됩니다.

입력 형식

첫 번째 줄에는 영역의 수 N(1 ≤ N ≤ 50)이 주어집니다. 각 영역에 대하여 두 개의 줄이 주어집니다.

  • 각 영역의 첫 번째 줄에는 감염 날짜가 주어지고, 두 번째 줄에는 증상 발생 날짜가 주어집니다.
  • 날짜의 첫 번째 정수는 월(1 ≤ M ≤ 12)을 나타내고, 두 번째 정수는 연도(0000 ≤ Y ≤ 0030)를 나타냅니다. 연도는 항상 4자리입니다.
  • 증상 발생 날짜감염 날짜보다 앞설 수 없습니다.

출력 형식

각 영역의 EIT를 각 줄에 출력합니다. EIT는 소수점 이하 5번째 자리에서 반올림하여 4번째 자리까지 출력하며, 한 자리 숫자는 0이더라도 반드시 출력해야 합니다.

BOJ 9428번 문제 풀이

주어진 규칙에 따라 EIT를 계산하면 됩니다. 필자의 경우 규칙을 이해하기에 약간 힘들었으나, 코드 구현의 난이도는 어렵지 않았습니다.

BOJ 9428번 소스 코드

C++
#include <bits/stdc++.h>

using namespace std;

int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    int N;
    cin >> N;

    for (int i = 0; i < N; i++) {
        int infection_month, infection_year;
        int strike_month, strike_year;
        cin >> infection_month >> infection_year;
        cin >> strike_month >> strike_year;

        double eit = 0.0;
        if (infection_year == strike_year) {
            int months = strike_month - infection_month;
            eit = 0.5 * months / (12.0 - infection_month + 1);
        } else {
            int years = strike_year - infection_year;
            eit = 0.5 + (years - 1) + (strike_month - 1) / 12.0;
        }

        cout.setf(ios::fixed);
        cout.precision(4);
        cout << eit << endl;
    }
}

댓글 남기기