题目
读入年份和月份(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