跪了,您点开了这个帖子,就看看把
#include <iostream>
#include <cstdio>
#include <cmath>
#define Before_0 1721424
#define Before_1582 2299239
using namespace std;
int Q;
int mon[15] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool leap_year (long long y) {
if (y < 0) {
if (abs(y + 1) % 4 == 0) return 1;
}
else if (y < 1582) {
if (y % 4 == 0) return 1;
}
else
if (y % 400 == 0 || (y % 100 != 0 && y % 4 == 0))
return 1;
return 0;
}
int getday (long long year) {
if (year < 0)
return (year + 4713) * 365 + (4713 / 4 + 1) - (-year + 3) / 4;
//分3中阶段,因为三种阶段计算闰年的方式不同
//第一个阶段只能根据变量算
//后两个可以直接给常量,免掉多余的
else if (year <= 1582)
return ((year - 1) * 365 + (year - 1) / 4) + Before_0;
else
return Before_1582 + ((year - 1583) * 365 + (year - 1 - 1580) / 4 - ((year - 1 - 1500) / 100 - (year - 1 - 1200) / 400));
}
//这里使用二分直接把年数算出来,然后到了
//主函数中用getday把这一年中的天数精准地
//计算出来
int er_fen (long long day) {
long long l = -4713, r = 1e9;
//l是当前最小,r是可能的最大值
while (l < r) {
long long mid = l + (r - l) / 2;
if (mid == 0) mid = 1;//特判,运行到了0年直接跳到公元1年
//把到这一年的天数算出来,然后和mid比较
//比较之后就可以做正常二分了
if (getday (mid) <= day) l = mid + 1;
else r = mid;
if(l == 0) l = 1; //左边界到0年,向右跨
if(r == 0) r = -1; //右边界到0年。向左跨
//反正就是不能到0年
}
if (l == 1) l = 0;
return l - 1;
}
int main() {
cin >> Q;
for (int t = 1; t <= Q; ++t) {
int r; cin >> r;
int year = er_fen(r);
int day = getday(year);
for (int i = 1; i <= 12; ++i) {
int max_day = mon[i]; //一个月中最多的天数
if (i == 2 && leap_year(year)) max_day++;
//和之前写的代码一样
if (year == 1582 && i == 10) max_day = 21;
//1582年10月扣完天数之后就只剩21天了
if (day + max_day > r) {
int day = r - day + 1;
if(year == 1582 && i == 10 && day > 4) day += 10;
cout << day << ' ' << i << ' ' << abs(year);
if(year < 0) cout << " BC";
cout << '\n';
break;
}
else {
day += max_day;
//反正就剩一点点了,直接加上去
}
}
}
return 0;
}
您告诉我我哪错了给您两个关注加五体投地