문제 설명

2024년은 윤년입니다. m1월 d1일이 월요일일 때, m2월 d2일까지 특정 요일 A가 몇 번 등장하는지 구하는 문제입니다.

입력 조건

  • 첫 번째 줄: m1, d1, m2, d2 (공백으로 구분)
  • 두 번째 줄: A (요일 문자열)
  • 1 ≤ m1 ≤ m2 ≤ 12
  • 1 ≤ d1, d2 ≤ 31
  • A는 Mon, Tue, Wed, Thu, Fri, Sat, Sun 중 하나

출력 조건

  • A 요일이 등장하는 횟수

풀이 접근

💡 Key Insight

1. 날짜를 일수로 변환
   - 각 월의 일수를 배열로 저정
   - 월별 누적 일수 계산

2. 요일을 숫자로 변환
   - Monday를 0으로 시작하여 Sunday를 6으로 매핑
   - 간단한 if-else 구조 사용

3. 시작일부터 종료일까지 순회
   - 현재 요일이 목표 요일과 같으면 카운트
   - 다음 날로 넘어갈 때마다 요일을 (현재 요일 + 1) % 7로 갱신

소스 코드

#include <iostream>
using namespace std;

// 특정 월, 일을 연중 몇 번째 날짜로 변환하는 함수
int NumOfDays(int m, int d) {
    // 각 월의 일수 (인덱스 1부터 시작)
    int days[13] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    int total_days = 0;

    // 이전 월까지의 일수 누적
    for(int i = 1; i < m; i++)
        total_days += days[i];

    // 현재 월의 일수 추가
    total_days += d;

    return total_days;
}

// 요일 문자열을 숫자로 변환하는 함수 (0: 월요일 ~ 6: 일요일)
int NumOfDay(string s) {
    if(s == "Mon") return 0;
    else if(s == "Tue") return 1;
    else if(s == "Wed") return 2;
    else if(s == "Thu") return 3;
    else if(s == "Fri") return 4;
    else if(s == "Sat") return 5;
    return 6;
}

int ans;

int main() {
    int m1, m2, d1, d2;
    string A;
    cin >> m1 >> d1 >> m2 >> d2;
    cin >> A;

    // 시작일과 종료일을 연중 날짜로 변환
    int start_date = NumOfDays(m1, d1);
    int end_date = NumOfDays(m2, d2);

    // 월요일부터 시작
    int cur_day = NumOfDay("Mon");

    // 날짜를 하나씩 증가시키며 확인
    for(int date = start_date; date <= end_date; date++) {
        if(cur_day == NumOfDay(A)) ans++;
        cur_day = (cur_day + 1) % 7;  // 다음 날의 요일
    }

    cout << ans;
    return 0;
}

주요 학습 포인트

  1. 날짜 계산의 기본

    • 월별 일수를 배열로 관리
    • 누적 일수 계산 방법
  2. 요일 처리

    • 요일의 숫자 표현 (0-6)
    • 모듈러 연산을 통한 요일 순환
  3. 자료구조 선택

    • 작은 크기의 고정 데이터는 단순 if-else가 효율적
    • unordered_map 같은 복잡한 자료구조는 불필요
  4. 코드 구조화

    • 기능별 함수 분리
    • 명확한 변수명 사용

개선 가능 사항

  1. ans를 전역 변수로 선언하는 대신 지역 변수로 사용
  2. 요일 변환 함수를 switch-case 문으로 변경하여 가독성 향상
  3. 날짜 유효성 검사 추가

예제 테스트

입력:
2 5 3 9
Sat

출력:
5

이 문제를 다시 풀 때는 날짜 계산의 기본 개념과 요일 처리 방식을 잘 기억하고, 불필요하게 unordered_map 같은 복잡한 자료구조를 피하는 것이 중요합니다.