🎲
<코드트리/C++> 그 요일은
January 02, 2025
문제 설명
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;
}
주요 학습 포인트
-
날짜 계산의 기본
- 월별 일수를 배열로 관리
- 누적 일수 계산 방법
-
요일 처리
- 요일의 숫자 표현 (0-6)
- 모듈러 연산을 통한 요일 순환
-
자료구조 선택
- 작은 크기의 고정 데이터는 단순 if-else가 효율적
- unordered_map 같은 복잡한 자료구조는 불필요
-
코드 구조화
- 기능별 함수 분리
- 명확한 변수명 사용
개선 가능 사항
- ans를 전역 변수로 선언하는 대신 지역 변수로 사용
- 요일 변환 함수를 switch-case 문으로 변경하여 가독성 향상
- 날짜 유효성 검사 추가
예제 테스트
입력:
2 5 3 9
Sat
출력:
5
이 문제를 다시 풀 때는 날짜 계산의 기본 개념과 요일 처리 방식을 잘 기억하고, 불필요하게 unordered_map 같은 복잡한 자료구조를 피하는 것이 중요합니다.