[CSP-S2020] 儒略日 题解

[CSP-S2020] 儒略日

今儿终于做掉困扰多年的题目了,其实想好细节也不难。

容易发现儒略历和格里高利历的润年判断方式不一样,并且中间有消失的十天,计算起来相当不方便。所以我们可以首先计算出 4713.1.11582.10.4 会经过多少天,可以通过一天一天暴力跳的方法计算出需要 2299160,那么对于小于等于该数字的情况,直接按照儒略历的计算方式从 4713.1.1 计算即可,否则先将天数减去 2299161 然后按照格里高利历从 1582.10.15 开始计算。

对于儒略历,可以发现,4年一闰,所以先除掉4年的天数,然后一月一月的跳,最后一天一天地跳。

对于格里高利历,400年总共有97闰,所以先400年跳,然后一年一年跳,再一月一月跳,最后一天一天跳。

对于代码实现,可以使用查表的方式简化计算。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL read() {
LL sum=0,flag=1; char c=getchar();
while(c<'0'||c>'9') {if(c=='-') flag=-1; c=getchar();}
while(c>='0'&&c<='9') {sum=sum*10+c-'0'; c=getchar();}
return sum*flag;
}
#define int LL
int T;
int year[2]={365,366};
int month[13][2]={{0,0},{31,31},{28,29},{31,31},{30,30},{31,31},{30,30},{31,31},{31,31},{30,30},{31,31},{30,30},{31,31}};
inline int chkru(int x) {
if(x<0) x++;
if(x%4==0) return 1;
else return 0;
}
inline int chkge(int x) {
if((x%4==0&&x%100!=0)||x%400==0) return 1;
else return 0;
}
inline void calc_ru(int n) {
int a=-4713,b=1,c=1;
a=a+4*int(n/1461); n%=1461;
if(a>=0) a++;
while(n>=month[b][chkru(a)]) {
n-=month[b][chkru(a)];
b++;
if(b==13) {
b=1;
if(a==-1) a=1;
else a++;
}
}
while(n--) {
c++;
if(c==month[b][chkru(a)]+1) {
c=1; b++;
if(b==13) {
b=1;
if(a==-1) a=1;
else a++;
}
}
}
if(a<0) cout<<c<<" "<<b<<" "<<-a<<" BC"<<endl;
else cout<<c<<" "<<b<<" "<<a<<endl;
}
inline void calc_ge(int n) {
int a=1582,b=10,c=15;
a=a+400*int(n/146097); n%=146097;
while(n>=year[chkge(a+1)]) {
n-=year[chkge(a+1)];
a++;
}
while(n>=month[b][chkge(a)]) {
n-=month[b][chkge(a)];
b++; if(b==13) {b=1; a++;}
}
while(n--) {
c++;
if(c==month[b][chkge(a)]+1) {
c=1; b++;
if(b==13) {b=1; a++;}
}
}
cout<<c<<" "<<b<<" "<<a<<endl;
}
signed main() {
cin>>T;
while(T--) {
int n; cin>>n;
if(n<=2299160) calc_ru(n);
else calc_ge(n-2299161);
}
}
posted @   2017BeiJiang  阅读(123)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!
点击右上角即可分享
微信分享提示