为了简便计算,天文学家们使用儒略日(Julian day)来表达时间。所谓儒略日,其定义为从公元前 4713 年 1 月 1 日正午 12 点到此后某一时刻间所经过的天数,不满一天者用小数表达。若利用这一天文学历法,则每一个时刻都将被均匀的映射到数轴上,从而得以很方便的计算它们的差值。
现在,给定一个不含小数部分的儒略日,请你帮忙计算出该儒略日(一定是某一天的中午 12 点)所对应的公历日期。
我们现行的公历为格里高利历(Gregorian calendar),它是在公元 1582 年由教皇格里高利十三世在原有的儒略历(Julian calendar)的基础上修改得到的(注:儒略历与儒略日并无直接关系)。具体而言,现行的公历日期按照以下规则计算:
第一行一个整数
Q
Q
Q,表示询问的组数。
接下来
Q
Q
Q 行,每行一个非负整数
r
i
r_i
ri,表示一个儒略日。
对于每一个儒略日 r i r_i ri,输出一行表示日期的字符串 s i s_i si。共计 Q Q Q 行。 s i s_i si 的格式如下:
Day Month Year
。其中日(Day)、月(Month)、年(Year)均不含前导零,中间用一个空格隔开。例如:公元7 11 2020
。Day Month Year BC
。其中年(Year)输出该年份的数值,其余与公元后相同。例如:公元前 841 年 2 月 1 日正午 121 2 841 BC
。3
10
100
1000
11 1 4713 BC
10 4 4713 BC
27 9 4711 BC
3
2000000
3000000
4000000
14 9 763
15 8 3501
12 7 6239
见附件中的 julian/julian3.in
见附件中的 julian/julian3.ans
【数据范围】
测试点编号 | Q = Q = Q= | r i ≤ r_i \le ri≤ |
---|---|---|
1 1 1 | 1000 1000 1000 | 365 365 365 |
2 2 2 | 1000 1000 1000 | 1 0 4 10^4 104 |
3 3 3 | 1000 1000 1000 | 1 0 5 10^5 105 |
4 4 4 | 10000 10000 10000 | 3 × 1 0 5 3\times 10^5 3×105 |
5 5 5 | 10000 10000 10000 | 2.5 × 1 0 6 2.5\times 10^6 2.5×106 |
6 6 6 | 1 0 5 10^5 105 | 2.5 × 1 0 6 2.5\times 10^6 2.5×106 |
7 7 7 | 1 0 5 10^5 105 | 5 × 1 0 6 5\times 10^6 5×106 |
8 8 8 | 1 0 5 10^5 105 | 1 0 7 10^7 107 |
9 9 9 | 1 0 5 10^5 105 | 1 0 9 10^9 109 |
10 10 10 | 1 0 5 10^5 105 | 年份答案不超过 1 0 9 10^9 109 |
特别友善的毒瘤题,3小时没调出来
可以用O(1)做的
不难发现,1200后400年可以作为一个周期,算出格里高利历4年的天数(
365
∗
3
+
366
=
1461
365*3+366=1461
365∗3+366=1461),就可以算出其400年的天数(
146097
146097
146097)
从4713年到1582年的儒略历的天数也可以算出来(
2299160
2299160
2299160),只需要判断r的大小便可判断出是格里高利历还是儒略历
为了方便,我们设自1200年1月1日起格里高利历开始,并减去跳过的天数(
2159351
2159351
2159351)
那么2159351怎么算?
首先算出
1461
∗
300
(
公元后
1.1.1
到
1200.1.1
的天数
)
+
4712
/
4
∗
1461
(
公元前
4713.1.1
到
1.1.1
的天数
)
=
2159358
1461*300(公元后1.1.1到1200.1.1的天数)+4712/4*1461(公元前4713.1.1到1.1.1的天数)=2159358
1461∗300(公元后1.1.1到1200.1.1的天数)+4712/4∗1461(公元前4713.1.1到1.1.1的天数)=2159358
我们减去2159358以此算出格里高利历的日期(应该再减去10天),但是,
因为我们认为格里高利历从1200年开始,因此认为1300,1400,1500年不是闰年,所以多减了3天
也就是2159358-10+3
#include
using namespace std;
#define int long long
const int N=146097;
int y[N],m[N],d[N];
int n,t;
int md(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;
}
signed main()
{
m[0]=d[0]=1;
for(int i=1;i<N;i++){//400年的周期中第几天在几月几日
d[i]=d[i-1]+1,m[i]=m[i-1],y[i]=y[i-1];
if(d[i]>md(y[i],m[i])) ++m[i],d[i]=1;
if(m[i]>12) ++y[i],m[i]=1;
}
int T;
cin>>T;
while(T--){
cin>>n;
if(n>2299160){
n-=2159351;
t=n/N*400+1200;
n%=N;
}
else{
t=n/1461*4-4712;
n%=1461;
}
if(t+y[n]>0) cout<<d[n]<<" "<<m[n]<<" "<<t+y[n]<<endl;
else cout<<d[n]<<" "<<m[n]<<" "<<1-t-y[n]<<" BC"<<endl;
}
}