题解
题目给定一个日期,要求我们实现一个获取 $n$ 天之后的程序,我们先考虑实现获取一天之后的日期的功能,然后我们只需要循环 $n$ 次便可解决问题。
那么如何实现一个获取 $1$ 天以后日期的功能呢?本质上日期就是一个动态的进位数值,它的第一位是 Day,第二位是 Month,第三位是 Year,我们只需要考量什么情况下会进位即可解决问题。
- Year 不需要进位所以我们直接跳过。
- Month 则是固定为每 $12$ 进位一次,因此只有 Day 的进位需要考虑,而 Day 的最大值是动态的,与 Year 和 Month 均有关系。
我们先令 Day 的最大值为 Days,我们观察月表可知,除了 $2$ 月,Day 的最大值与 Year 没有关系,因此我们先判断 Month 是否为 $2$:
- 如果否,我们直接使用 Switch 语句把每一个月的 Case 写上(相当于写了一堆 if-else)。
- 如果 Month 为 $2$,那么我们判断当前年份是否是闰年,如果是闰年则 Days 为 $29$,否则 Days 为 $28$。
现在我们直接模拟进位,让 Day += 1,并判断 Day 和 Days 的关系:如果 Day 等于 Days (即达到进位阈值),那么令 Day 为 $1$,并让 Month += 1,然后同样的,我们判断 Month 是否等于 $13$,如果是则令 Month 为 $1$,然后 Year += 1,由于 Year 不需要再进位,所以结束,直接输出即可!
C++
#include <bits/stdc++.h>
using i128 = __int128;
using ll = long long;
using ull = unsigned long long;
using de = double;
using ld = long double;
using namespace std;
struct Date
{
int year;
int month;
int day;
void tomorrow()
{
int Days;
if (month == 2)
{
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) Days = 29;
else Days = 28;
}
else switch (month)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
Days = 31;
break;
default: Days = 30;
}
if (day == Days)
{
month++, day = 1;
if (month == 13) month = 1, year++;
}
else day++;
}
};
void solve()
{
Date date; int n;
scanf("%d-%d-%d %d", &date.year, &date.month, &date.day, &n);
for (int i = 0; i < n; i++) date.tomorrow();
printf("%04d-%02d-%02d\n", date.year, date.month, date.day);
}
int main()
{
// ios::sync_with_stdio(0);
// cin.tie(0);
// cout.tie(0);
int t = 1;
cin >> t;
while (t--)
{
solve();
}
}