解题思路
在题目这种历法中,日期计算以400年为周期,每400年都有恰好146097天。
我们可以预处理出400年内的情况,将年份模400即可快速得到答案。
加速技巧
对于“格里高利历”,以1200年1月1日为起始日,r减去2159351天 r⩽2299160即为儒略历。公元前x年视为(1-x)年。
参考代码
#include <bits/stdc++.h>
using namespace std;
const int N = 146097, A = 2299160, B = 2159351, C = 1461, D = 4712;
int y[N], m[N], d[N];
inline int get(int y, int m) {
if (m == 2) {
return (y % 4) ? 28 : (y % 100) ? 29 : y % 400 ? 28 : 29;
}
return (m == 4 || m == 6 || m == 9 || m == 11) ? 30 : 31;
}
void init() {
m[0] = d[0] = 1;
for(int i = 1; i < N; ++i) {
d[i] = d[i - 1] + 1; m[i] = m[i - 1]; y[i] = y[i - 1];
if (d[i] > get(y[i], m[i])) {
++m[i]; d[i] = 1;
}
if (m[i] > 12) {
++y[i]; m[i] = 1;
}
}
}
int main() {
init();
int T; cin >> T;
while (T--) {
long long n, t; cin >> n;
if (n > A) {
n -= B; t = n / N * 400 + 1200; n %= N;
} else {
t = n / C * 4 - D; n %= C;
}
if (t + y[n] > 0) {
cout << d[n] << ' ' << m[n] << ' ' << t + y[n] << '\n';
} else {
cout << d[n] << ' ' << m[n] << ' ' << 1 - t - y[n] << " BC\n";
}
}
return 0;
}