题解
输出日期差
1 条题解
-
0
解题思路
要算两个日期相差多少天,我们可以先定一个"起点",比如公元 1 年 1 月 1 日。然后写一个函数,把任意日期都换算成"从起点到这一天一共有多少天"。这样两个日期都换成天数后,相减就是它们相差的天数。
题目还特别说明:计算差值时包括第二个日期那一天,不包括第一个日期那一天。这正好等于 days(第二个日期) - days(第一个日期),因为 days 数的是"到这一天为止一共多少天",相减时第二天的当天被算进去了,第一天的当天被减掉了。
换算天数的时候,最麻烦的是闰年。闰年的判断规则是:
- 能被 4 整除,但不能被 100 整除;
- 或者能被 400 整除。
闰年的 2 月有 29 天,比平年多 1 天。
函数 days(y, m, d) 这样做:
- 先把 y 之前的每一年都加上天数:平年加 365,闰年加 366;
- 再把今年已经过去的月份的天数加起来(2 月要看是不是闰年);
- 最后加上当月已经过去的天数 d。
题目要求用 scanf 和 printf 来输入输出,年份按 YYYY-MM-DD 格式读入。
参考代码
// P4514 输出日期差:计算两个日期相差的天数(含结束日,不含开始日) #include <cstdio> using namespace std; // 判断y年是否为闰年 bool isLeap(int y) { return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0; } // 返回从公元1年1月1日到y年m月d日一共经过的天数 int days(int y, int m, int d) { int mon[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int sum = 0; for (int i = 1; i < y; i++) { // 累加整年的天数(闰年多1天) sum += 365 + isLeap(i); } for (int i = 1; i < m; i++) { // 累加本年已过月份的天数 sum += mon[i]; } if (m > 2 && isLeap(y)) sum++; // 闰年且已经过了2月,再加1天 sum += d; // 加上当月已经过的天数 return sum; } int main() { int y1, m1, d1, y2, m2, d2; scanf("%d-%d-%d %d-%d-%d", &y1, &m1, &d1, &y2, &m2, &d2); // 差值 = 后一天数 - 前一天数(含后一天、不含前一天,正好等于天数差) printf("%d ", days(y2, m2, d2) - days(y1, m1, d1)); return 0; }复杂度分析
每个日期都要循环一遍,把年份和月份都加一遍。年份最多是四位数,所以每次调用大约要算几千次,时间复杂度是 O(年份数),非常快。只用了几个变量和一个大小固定的月份表,空间复杂度是 O(1)。
- 1