题目

读入年份和月份(1~12),输出该月有多少天。

输入格式:一行输入两个正整数,分别表示年份和月份(1~12),以空格分隔。

输出格式:输出一个整数表示该月天数;若月份输入不在 1~12 范围内,输出 无效月份。末尾换行。

数据范围与约定:1 ≤ 年份 ≤ 9999,月份为整数。

思路与算法

1. 月份天数分类
公历月中:
大月(31 天):1、3、5、7、8、10、12 月;
小月(30 天):4、6、9、11 月;
2 月天数由年份是否为闰年决定:闰年 29 天,平年 28 天。

2. 分支组织
可以使用 switch - case 穿透特性将天数相同的月份合并处理,也可以维护一个长度为 13 的数组静态查表。无论哪种写法,都必须先对非法的月份范围(<1 或 >12)进行拦截。

完整程序

#include <stdio.h>

// 闰年判断辅助函数
static int is_leap(int year)
{
    return (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
}

int main(void)
{
    int year, month;
    if (scanf("%d %d", &year, &month) != 2) {
        return 1;
    }
    int days;
    switch (month) {
    // 利用 switch case 的穿透特性将所有 31 天的大月合并处理
    case 1: case 3: case 5: case 7: case 8: case 10: case 12:
        days = 31;
        break;
    // 合并所有 30 天的小月
    case 4: case 6: case 9: case 11:
        days = 30;
        break;
    case 2:
        // 2 月根据是否为闰年决定是 29 天还是 28 天
        days = is_leap(year) ? 29 : 28;
        break;
    default:
        printf("无效月份\n");
        return 0;
    }
    printf("%d\n", days);
    return 0;
}

运行示例

示例 1:

输入:

2024 2

输出:

29

示例 2:

输入:

2023 2

输出:

28

其它写法

下面每种写法都是完整程序,输入输出格式与正文一致,便于对照。

月份天数表

程序:

#include <stdio.h>

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

int main(void)
{
    int y, m;
    if (scanf("%d %d", &y, &m) != 2) {
        return 1;
    }
    int d[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    if (m < 1 || m > 12) {
        printf("无效月份\n");
        return 0;
    }
    int days = d[m];
    if (m == 2 && is_leap(y)) {
        days = 29;
    }
    printf("%d\n", days);
    return 0;
}

输入:

2024 2

输出:

29