原代码(考场调了50min):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int Dim[2][13] = {{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
const ll TS_105 = 2299161;
ll calc_year_in_period(ll va) {
if (va >= 366) return 1 + (va - 366) / 365;
else return 0;
}
ll calc_days_in_year(ll year) {
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) return 366;
return 365;
}
// calc the date <= 1582.10.5
ll calc_date_before(ll x, ll& Y, ll& M, ll& D) {
if (x > TS_105) return x - TS_105;
ll pers = x / 1461, vals = x % 1461;
Y = calc_year_in_period(vals);
D = vals; if (Y) D -= 366 + 365 * (Y - 1);
for (M = 1; D + 1 > Dim[bool(Y)][M]; D -= Dim[bool(Y)][M++]);
Y += pers * 4 - 4713; if (Y >= 0) ++Y; ++D; return 0;
}
// calc the date >= 1582.10.15, x is the time - 1582.10.5
void calc_date_after(ll x, ll& Y, ll& M, ll& D) {
ll d = x + 139444; // days from 1201.1.1 to Y.M.D
ll pers = d / 146097, vals = d % 146097, g=vals; // a period is 400 years. eg 1201.1.1 to 1600.12.31
ll y; for (y=1201; g >= calc_days_in_year(y); g -= calc_days_in_year(y++));
bool od = !(y % 4 == 0 && y % 100 != 0 || y % 400 == 0);
for (M = 1; M < 12 && g + 1 > Dim[od][M]; g -= Dim[od][M++]);
D = g+1; Y = y + pers * 400; //printf("M=%lld\n", M);
}
void solve(ll x, ll& Y, ll& M, ll& D) {
ll det = calc_date_before(x, Y, M, D);
if (det == 0) return;
calc_date_after(det, Y, M, D);
}
int main() {
int Q; ll inp, a, b, c;
scanf("%d", &Q); while (Q--) {
scanf("%lld", &inp);
a=b=c=0; solve(inp, a, b, c);
printf("%lld %lld %lld%s\n", c,b,a<0?-a:a,a<0?" BC":"");
}
return 0;
}
然后发现输入 2299161 输出 5 10 1582
才发现题目看错了。。加了个关于 2299161 数据的特判
if (inp == TS_105) a=1582,b=10,c=15; else solve(inp,a,b,c);
就AC了,想问一下难道后6个点里面都有 2299161 这个数?这数据好离谱