洛谷 P7075 [CSP-S2020] 儒略日

P7075 [CSP-S2020] 儒略日

1.题目描述

为了简便计算,天文学家们使用儒略日(Julian day)来表达时间。所谓儒略日,其定义为从公元前 4713 年 1 月 1 日正午 12 点到此后某一时刻间所经过的天数,不满一天者用小数表达。若利用这一天文学历法,则每一个时刻都将被均匀的映射到数轴上,从而得以很方便的计算它们的差值。

现在,给定一个不含小数部分的儒略日,请你帮忙计算出该儒略日(一定是某一天的中午 12 点)所对应的公历日期。

我们现行的公历为格里高利历(Gregorian calendar),它是在公元 1582 年由教皇格里高利十三世在原有的儒略历(Julian calendar)的基础上修改得到的(注:儒略历与儒略日并无直接关系)。具体而言,现行的公历日期按照以下规则计算:

  1. 公元 1582 年 10 月 15 日(含)以后:适用格里高利历,每年一月 3131 天、 二月 2828 天或 2929 天、三月 3131 天、四月 3030 天、五月 3131 天、六月 3030 天、七月 3131 天、八月 3131 天、九月 3030 天、十月 3131 天、十一月 3030 天、十二月 3131 天。其中,闰年的二月为 2929 天,平年为 2828 天。当年份是 400400 的倍数,或日期年份是 44 的倍数但不是 100100 的倍数时,该年为闰年。
  2. 公元 1582 年 10 月 5 日(含)至 10 月 14 日(含):不存在,这些日期被删除,该年 10 月 4 日之后为 10 月 15 日。
  3. 公元 1582 年 10 月 4 日(含)以前:适用儒略历,每月天数与格里高利历相同,但只要年份是 44 的倍数就是闰年。
  4. 尽管儒略历于公元前 45 年才开始实行,且初期经过若干次调整,但今天人类习惯于按照儒略历最终的规则反推一切 1582 年 10 月 4 日之前的时间。注意,公元零年并不存在,即公元前 1 年的下一年是公元 1 年。因此公元前 1 年、前 5 年、前 9 年、前 13 年……以此类推的年份应视为闰年。

2.输入格式

第一行一个整数 QQ,表示询问的组数。
接下来 QQ 行,每行一个非负整数 r_iri,表示一个儒略日。

3.输出格式

对于每一个儒略日 r_iri,输出一行表示日期的字符串 s_isi。共计 QQ 行。 s_isi 的格式如下:

  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

4.输入输出样例

输入#1                                                               输出#1

3                                      11 1 4713 BC
10 10 4 4713 BC
100 27 9 4711 BC
1000

输入#2                                                               输出#2

3                                      14 9 763
2000000                                15 8 3501
3000000                                12 7 6239
4000000

5.题意

计算公元前 4713年 1 月 1 日正午 12 点到此后某一时刻间所经过的天数。计算出该儒略日(一定是某一天的中午 12 点)所对应的公历日期。

6.思路

利用每四年有一个闰年的规律(三平年一闰年),分为三个周期

一(1851前)

大周期为四年,小周期为一年的一月划分,处理这些天数即可

二(1852)

周期为一月,处理天数(10月因4 日之后为 10 月 15 日,所以要特殊计算)

三(1853后)

最大的周期为四百年,然后分别是100,年,一年,一月,分别处理天数

7.代码实现

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int A;
int pn[12]={31,28,31,30,31,30,31,31,30,31,30,31};//平年的一月周期
int rn[12]={31,29,31,30,31,30,31,31,30,31,30,31};//闰年的一月周期
int sp[12]={31,28,31,30,31,30,31,31,30,21,30,31};//1582的一月周期
int yp[4]={366,365,365,365};//一年周期
ll n,ans;
void solve1()//四年一闰 (第一周期)
{
ans=n/1461*4;n%=1461;ll p,q;//四年周期 366+365+365+365=1461366+365+365+365=1461 ,一个闰年加三个平年
for(p=0;p<4 && n>=yp[p];p++)
n-=yp[p],ans++;//一年周期
if(!p)//第一年为闰年
for(q=0;q<12 && n>=rn[q];q++)
n-=rn[q];//闰年的一月周期
else
for(q=0;q<12 && n>=pn[q];q++)
n-=pn[q];//平年的一月周期
if(ans<4713)
printf("%lld %lld %lld BC\n",n+1,q+1,4713-ans);//公元前
else
printf("%lld %lld %lld\n",n+1,q+1,ans-4713+1);//公元后
}
void solve2()//世纪年四次一闰(第二周期 )
{
n-=2299239;ans=1583;ll p,q;// 1582 年的基础上加上 1582 一年 2298884+355=2299239
if(n<365)//1583
for(q=0;q<12 && n>=pn[q];q++)
n-=pn[q];//平年的一月周期
else
if(n<6209)// 1584-1599 四个完整的四年周期加上 1583年 1461×4+365=6209
{
n-=365;ans++;
ans+=n/1461*4;n%=1461;// 四个完整的四年周期
for(p=0;p<4 && n>=yp[p];p++)
n-=yp[p],ans++;
if(!p)
for(q=0;q<12 && n>=rn[q];q++)
n-=rn[q];
else
for(q=0;q<12 && n>=pn[q];q++)
n-=pn[q];
}
else// 1584-1599 四个完整的四年周期加上 1583年
{
n-=6209;ans=1600;
ans+=n/146097*400;n%=146097;//四百年周期
if(n<366)//只有第一个世纪年为闰年
for(q=0;q<12 && n>=rn[q];q++)
n-=rn[q];
else
{
n--;//假设第一个世纪年是平年,按照一百年周期计算
ans+=n/36524*100;n%=36524;//一百年周期
if(n<365)//其余的世纪年均为平年
for(q=0;q<12 && n>=pn[q];q++)
n-=pn[q];
else
{
n++;//假设世纪年为闰年,按照四年周期计算
ans+=n/1461*4;n%=1461;
for(p=0;p<4 && n>=yp[p];p++)
n-=yp[p],ans++;
if(!p)
for(q=0;q<12 && n>=rn[q];q++)
n-=rn[q];
else
for(q=0;q<12 && n>=pn[q];q++)
n-=pn[q];
}
}
}
printf("%lld %lld %lld\n",n+1,q+1,ans);
}
void solve3()//4713 B.C - 1581 A.D 的所有完整的四年周期加上 1580,1581 两年
{
n-=2298884;ans=1582;ll q;
for(q=0;q<12 && n>=sp[q];q++)
n-=sp[q];
if(q==9 && n>3)//10 月 4 日之后为 10 月 15 日
n+=10;
printf("%lld %lld %lld\n",n+1,q+1,ans);
}
int main()
{
scanf("%d",&A);
while(A--)
{
scanf("%lld",&n);
if(n<2298884)
solve1();
else
if(n>2299238)
solve2();
else
solve3();
}
return 0;
}

posted on   时66  阅读(107)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

点击右上角即可分享
微信分享提示