NC213853. [CSP2020]儒略日(julian)
描述
题目数据为官方数据,可以提交测试,结果仅供参考,不代表官方成绩,最终成绩以官方发布的最终成绩为准。
为了简便计算,天文学家们使用儒略日(Julian day)来表达时间。所谓儒略日,其定义为从公元前 4713 年 1 月 1 日正午 12 点到此后某一时刻间所经过的天数,不满一天者用小数表达。若利用这一天文学历法,则每一个时刻都将被均匀的映射到数轴上,从而得以很方便的计算它们的差值。
现在,给定一个不含小数部分的儒略日,请你帮忙计算出该儒略日(一定是某一天的中午 12 点)所对应的公历日期。
我们现行的公历为格里高利历(Gregorian calendar),它是在公元 1582 年由教皇格里高利十三世在原有的儒略历(Julian calendar)的基础上修改得到的(注:儒略历与儒略日并无直接关系)。具体而言,现行的公历日期按照以下规则计算:
输入描述
第一行一个整数 ,表示询问的组数。
接下来 行,每行一个非负整数 ,表示一个儒略日。
输出描述
对于每一个儒略日 ,输出一行表示日期的字符串 。共计 行。 的格式如下:
1.若年份为公元后,输出格式为 Day Month Year。其中日(Day)、月(Month)、年(Year)均不含前导零,中间用一个空格隔开。例如:公元2020 年 11 月 7 日正午 12 点,输出为 7 11 2020。2.若年份为公元前,输出格式为 Day Month Year BC。其中年(Year)输出该年份的数值,其余与公元后相同。例如:公元前 841 年 2 月 1 日正午 12点,输出为 1 2 841 BC。
示例1
输入:
3 10 100 1000
输出:
11 1 4713 BC 10 4 4713 BC 27 9 4711 BC
示例2
输入:
3 2000000 3000000 4000000
输出:
14 9 763 15 8 3501 12 7 6239
C++(clang++11) 解法, 执行用时: 45ms, 内存消耗: 3400K, 提交时间: 2020-11-09 21:01:09
#include<bits/stdc++.h> typedef long long ll; int T,y[146097],m[146097],d[146097]; ll n,t; inline 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; } int main(){ m[0]=d[0]=1; for(int i=1;i<146097;++i){ 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; } scanf("%d",&T); while(T--){ scanf("%lld",&n); if(n>2299160){ n-=2159351; t=n/146097*400+1200; n%=146097; }else{ t=n/1461*4-4712; n%=1461; } if(t+y[n]>0)printf("%d %d %lld\n",d[n],m[n],t+y[n]); else printf("%d %d %lld BC\n",d[n],m[n],1-t-y[n]); } }