题解:P12843 [蓝桥杯 2025 国 A] 生日相遇问题
题意很好理解。
其实这道题就纯大模拟吧 @-@。
在每一年中干如下几件事:
-
闰年判断:根据规则判断某年是否为闰年(年份能被
4 整除但不能被100 整除,或能被400 整除)。 -
计算一年中的第几天(doy):对于给定的日期,计算它在该年中是第几天,注意处理
2 月29 日在非闰年的情况(视为2 月28 日)。 -
星期递推:从
2025 年1 月1 日为星期三开始,递推每年1 月1 日的星期几。平年下一年1 月1 日星期数增加1 (365 对7 取模为1 ),闰年增加2 (366 对7 取模为2 )。 -
比较生日的星期几:对于每一年,计算小蓝和小乔生日的星期几,如果相同则记录该年份。
Code:
#include <iostream>
#include <vector>
using namespace std;
const int N = 1e5;
int m, d1, n, d2, k;
int ans[N];
int idx;
inline bool isleap (int year) {
return (!(year % 4) and year % 100) or (!(year % 400));
}
int getdoy(int month, int day, int year) {
int months[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// 每个月的天数
if (isleap(year)) months[1] = 29;
else months[1] = 28;
if (month == 2 and day == 29 and !isleap(year)) {
// 特判 2 月 29 日
day = 28;
}
int doy = 0;
for (int i = 0; i <= month - 2; i++) {
doy += months[i];
}
doy += day;
return doy;
}
int main() {
cin >> m >> d1 >> n >> d2 >> k;
int st = 2025;
int en = st + k;
int now = 3; // 2025 年 1 月 1 日是星期三
for (int year = st; year < en; year++) {
int doy1 = getdoy(m, d1, year);
int w1 = (now + doy1 - 1) % 7;
int doy2 = getdoy(n, d2, year);
int w2 = (now + doy2 - 1) % 7;
if (w1 == w2) {
ans[++ idx] = year;
} if (isleap(year)) {
now = (now + 366) % 7;
} else {
now = (now + 365) % 7;
}
}
if (idx == 0) {
cout << "No Answer";
} else {
for (int i = 1; i <= idx; i ++) {
cout << ans[i] << '\n';
}
}
return 0;
}