문제
D M Y 형식으로 주어진 날짜가 유효한지 검사한다. 윤년 규칙을 포함하여 날짜의 유효성을 판단하고 Valid 또는 Invalid를 출력한다.
윤년 판단 조건:
- 4의 배수이면서
- 100의 배수가 아니거나, 400의 배수인 경우
0 0 0이 입력되면 종료한다.
입력
- 여러 줄에 걸쳐
D M Y형식의 날짜가 주어진다. 0 0 0이 입력되면 종료한다.
출력
- 각 날짜에 대해
Valid또는Invalid를 출력한다.
예제
| 입력 | 출력 |
|---|---|
29 2 2000 29 2 1900 31 4 2001 0 0 0 | Valid Invalid Invalid |
풀이
월별 최대 일수 배열을 정의하고, 입력된 날짜가 유효한지 단계적으로 검사한다.
0 0 0입력이 들어오면 반복을 종료한다.- 월이 1~12 범위를 벗어나면
Invalid로 처리한다. - 월이 2월인 경우, 윤년 여부를 판단하여 허용 최대 일을 29 또는 28로 결정한다.
- 나머지 월은 월별 최대 일수 배열(
days[])을 참조하여 일의 범위를 검사한다. - 모든 조건을 통과하면
Valid, 하나라도 실패하면Invalid를 출력한다.
핵심 아이디어: 윤년 판단 로직 (Y % 4 == 0 && (Y % 100 != 0 || Y % 400 == 0))을 정확히 구현하는 것이 핵심이다. 월별 최대 일수 배열을 미리 정의하면 2월을 제외한 나머지 월의 검증을 간결하게 처리할 수 있다.
코드
#include <iostream>
using namespace std;
int Y, M, D;
int days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cin >> D >> M >> Y;
while (D + M + Y)
{
bool chk = 1;
if (M < 1 || M > 12)
chk = 0;
else if (M == 2)
{
if (Y % 4 == 0 && (Y % 100 || Y % 400 == 0))
{
if (D < 1 || D > 29)
chk = 0;
}
else
{
if (D < 1 || D > 28)
chk = 0;
}
}
else
{
if (D < 1 || D > days[M])
chk = 0;
}
if (chk)
cout << "Valid\n";
else
cout << "Invalid\n";
cin >> D >> M >> Y;
}
}복잡도
- 시간: O(N) — N개의 날짜 각각 O(1) 처리
- 공간: O(1) — 상수 크기의 월별 일수 배열만 사용