题目没什么好解释的(某些大佬推出了公式,然而我又不会……)
参考代码如下(原谅我考完后完善的这个毒瘤码风):
#include <cctype>
#include <cstdio>
//#define LOCAL_JUDGE
int month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
typedef long long ll;
inline ll read(void) {
ll x = 0; bool f = 1; char ch = getchar();
for (; !isdigit(ch); ch = getchar()) if (ch == '-') f = 0;
for (; isdigit(ch); ch = getchar()) x = (x * 10) + (ch ^ 48);
return f ? x : -x;
}
void get(ll &mon, ll &r, bool run) {
for (int i = 1; i <= 12; ++i) {
r -= month[i];
if (run && i == 2) r--;
mon = i;
if (r <= 0) {
r += month[i];
if (run && i == 2) r++;
break;
}
}
}
void get_2(ll &mon, ll r, ll &day, ll &year, bool run) {
// 以下是特判1583年的情况
if (r <= 365) {
run = false;
year = 1583;
get(mon, r, run);
day = r;
return;
}
// 以下是特判1584年的情况
r -= 365;
if (r <= 366) {
year = 1584;
get(mon, r, 1);
day = r;
return;
}
// 以下是特判1585 - 1600年的情况
r -= 366;
if (r <= 4 * 1461) {
ll tmp = r / 1461, rest = r % 1461;
year = 1584 + tmp * 4 + (rest != 0);
if (rest == 0) day = 31, mon = 12;
else if (rest >= 1096) {
run = true; rest -= 1095, year += 3;
get(mon, rest, run);
day = rest;
}else {
ll tmp_2 = rest / 365, rest_2 = rest % 365;
year += tmp_2, run = false;
if (rest_2 == 0) day = 31, mon = 12, --year;
else get(mon, rest_2, run), day = rest_2;
}
return;
}
// 解决1601 以后的情况(直接算年数)
r -= 4 * 1461;
ll tmp = r / 146097, res = r % 146097; //tmp代表着有多少个400年
year = 1600 + tmp * 400;
if (res == 0) day = 31, mon = 12;
else if (res >= 109573) {
//在 301 - 400内, 400为闰
year += 300, res -= 109572;
ll tmp_2 = res / 1461, rest = res % 1461;
year += tmp_2 * 4 + (rest != 0);
if (rest == 0) day = 31, mon = 12;
else if (rest >= 1096) {
run = true; rest -= 1095, year += 3;
get(mon, rest, run);
day = rest;
}else {
ll tmp_2 = rest / 365, rest_2 = rest % 365;
year += tmp_2, run = false;
if (rest_2 == 0) day = 31, mon = 12, --year;
else get(mon, rest_2, run), day = rest_2;
}
return;
}
else {
//在1 - 300年内的处理
ll tmp1 = res / 36524, res1 = res % 36524;
year += tmp1 * 100;
if (res1 == 0) day = 31, mon = 12;
else if (res1 <= 35064) {
ll tmp2 = res1 / 1461, rest = res1 % 1461;
year += tmp2 * 4 + (rest != 0);
if (rest == 0) day = 31, mon = 12;
else if (rest >= 1096) {
run = true; rest -= 1095, year += 3;
get(mon, rest, run);
day = rest;
}else {
ll tmp_2 = rest / 365, rest_2 = rest % 365;
year += tmp_2, run = false;
if (rest_2 == 0) day = 31, mon = 12, --year;
else get(mon, rest_2, run), day = rest_2;
}
}
else {
res1 -= 35064; year += 96;
ll tmp_2 = res1 / 365, rest_2 = res1 % 365;
year += tmp_2 + (rest_2 != 0), run = false;
if (rest_2 == 0) day = 31, mon = 12;
else get(mon, rest_2, run), day = rest_2;
}
}
}
inline void work(void) {
int q = read();
while (q--) {
ll r = read() + 1;
ll year = 0, mon = 0, day = 0;
bool flag = false, run = false;
if (r <= (431148 + 1289910 + 366)) {
// 以下是公元前的判断
if (r <= 366) {
flag = true; run = true; year = 4713;
get(mon, r, run);
day = r;
}
else {
r -= 366; flag = true;
ll tmp = r / 1461, rest = r % 1461;
year = 4713 - tmp * 4 - (rest != 0);
if (rest == 0) day = 31, mon = 12;
else if (rest >= 1096) {
run = true; rest -= 1095, year -= 3;
get(mon, rest, run);
day = rest;
}
else {
ll tmp_2 = rest / 365, rest_2 = rest % 365;
year -= tmp_2, run = false;
if (rest_2 == 0) day = 31, mon = 12, ++year;
else get(mon, rest_2, run), day = rest_2;
}
}
}
else {
//公元1年-1580年的判断
r -= (431148 + 1289910 + 366); flag = false;
if (r <= 577095) {
ll tmp = r / 1461, rest = r % 1461;
year = 0 + tmp * 4 + (rest != 0);
if (rest == 0) day = 31, mon = 12;
else if (rest >= 1096) {
run = true; rest -= 1095, year += 3;
get(mon, rest, run);
day = rest;
}else {
ll tmp_2 = rest / 365, rest_2 = rest % 365;
year += tmp_2, run = false;
if (rest_2 == 0) day = 31, mon = 12, --year;
else get(mon, rest_2, run), day = rest_2;
}
}
else {
r -= 577095;
if (r <= 365) {
run = false; year = 1581;
get(mon, r, run);
day = r;
}
else {
r -= 365;
if (r <= 355) {
run = false; year = 1582;
month[10] = 21;
get(mon, r, run);
if (mon == 10 && r >= 5) r += 10;
day = r;
month[10] = 31;
}
else {
r -= 355;
get_2(mon, r, day, year, 0);
}
}
}
}
printf("%lld %lld %lld", day, mon, year);
if (flag) printf(" BC\n");
else putchar('\n');
}
}
int main(void) {
#ifndef LOCAL_JUDGE
freopen("julian.in", "r", stdin);
freopen("julian.out", "w", stdout);
#endif
work();
return 0;
}