题目要求我们根据输入的年份和月份,输出该月份有多少天。已知年份范围为 2000≤A≤3000,月份范围为 1≤B≤12,都属于正常范围,不需要考虑非法输入。核心问题在于正确处理 平年与闰年 的2月天数,以及区分 大月(31天) 和 小月(30天)。
解决这个问题可以分为两步:
判断闰年
闰年满足下面两个条件之一:
根据月份输出天数
这样,我们只需要用 if-else 或 switch 结构依次判断月份即可。因为条件互斥,直接按顺序判断不会出错。
代码中使用一个布尔变量 leap 来记录是否为闰年,初始值为 false,然后通过两步判断将其置为 true(如果是闰年)。随后按照“大月 → 小月 → 闰年2月 → 平年2月”的顺序进行判断并输出。
这种写法的好处是逻辑清晰,易于理解。代码容易扩展到其他年份范围(如输入年份超出范围,也符合现行公历规则)。
整个程序只进行了常数次的条件判断和输入输出操作,没有使用循环或递归,因此时间复杂度为:
以下为 C++ 参考代码,并逐段加以解释:
cpp1#include <iostream> 2using namespace std; 3int main() { 4 int y = 0, m = 0; 5 cin >> y >> m; 6 bool leap = false; // 判断闰年 7 if (y % 400 == 0) 8 leap = true; 9 if (y % 4 == 0 && y % 100 != 0) 10 leap = true; 11 if (m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12) 12 cout << 31 << endl; // 大月 13 else if (m == 4 || m == 6 || m == 9 || m == 11) 14 cout << 30 << endl; // 小月 15 else if (leap) 16 cout << 29 << endl; // 闰年 2 月 17 else 18 cout << 28 << endl; // 平年 2 月 19 return 0; 20}
代码段解释:
#include <iostream> 和 using namespace std;:引入输入输出库,并直接使用标准命名空间。int main():程序入口。int y = 0, m = 0;:定义年份变量 y 和月份变量 m 并初始化为 0。cin >> y >> m;:读取用户输入的年份和月份。bool leap = false;:设定标志位,假定最初不是闰年。if (y % 400 == 0) leap = true;:能被 400 整除,一定是闰年。if (y % 4 == 0 && y % 100 != 0) leap = true;:能被 4 整除且不能被 100 整除,也是闰年。两种判断方式并列,满足任意之一即置为 true。if 列出所有大月,直接输出 31。else if 列出所有小月,输出 30。else if (leap) 对应 2 月且为闰年,输出 29。else 对应平年 2 月,输出 28。return 0;:程序正常结束。这种分支结构保证了无论什么情况,只会执行其中一个输出语句,不会出现矛盾。
补充说明:
如果为了方便记忆,也可以将闰年判断合并成一个条件:
cpp1bool leap = (y % 400 == 0) || (y % 4 == 0 && y % 100 != 0);
效果完全一致。原代码的写法则是将其拆开,便于初学者理解每一步的逻辑。