题目

定义表示日期的结构体 Date(包含年、月、日),从标准输入读入年月日,综合考虑大小月与闰年二月天数,判断该日期是否为合法日历日期。

输入格式:一行输入三个正整数,分别表示年、月、日。

输出格式:若为合法日期输出 yes,否则输出 no,末尾换行。

数据范围与约定:1 ≤ 年 ≤ 9999。

思路与算法

1. 多维约束校验
① 检查月份是否在 1~12 之间;
② 根据年份判定闰年,确定 2 月最大天数(28 或 29);
③ 检查日是否在 1 到对应月份的最大天数之间。

2. 结构体组织逻辑
将日期字段封装进结构体,通过独立函数 int is_valid_date(struct Date d) 返回布尔状态。

完整程序

#include <stdio.h>

static int is_leap(int y)
{
    return (y % 400 == 0) || (y % 4 == 0 && y % 100 != 0);
}

// 查表法获取某年某月的实际天数
static int days_in_month(int y, int m)
{
    // 下标 1~12 对应月份天数,0 号位置占位
    int d[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
    // 闰年 2 月有 29 天
    if (m == 2 && is_leap(y)) {
        return 29;
    }
    return d[m];
}

int main(void)
{
    int y, m, d;
    if (scanf("%d %d %d", &y, &m, &d) != 3) {
        return 1;
    }

    // 日期有效性判定:月份在 1~12 之间,日不小于 1 且不超过当月最大天数
    if (m < 1 || m > 12 || d < 1 || d > days_in_month(y, m)) {
        printf("no\n");
    } else {
        printf("yes\n");
    }
    return 0;
}

运行示例

输入:

2024 2 29

输出:

yes