CSP 2020 T1 儒略日
description
solution:
十分清新的大模拟题(大家都写得十分愉快吧)
话说解法并不复杂,大概分为以下几部分
- 公元前
- 公元后到\(1582.10.4\)
- \(1582.10.15\)到无限的将来
首先容易知道确定了年份后日期计算十分容易
对于四年一闰的情况(即\(1582.10.4\)以前),判断位于哪一个四年,再判断具体在那一年
对于百年不闰四百年再闰的情况(即\(1582.10.15\)以后),判断位于哪一个四百年,再判断具体在那一年(可以直接暴力枚举判断)
其实就这么多了
特别地,对于我自己的程序要特判某些特定年份的\(12.31\),可能是写得太丑了
p.s.会遇到一大堆常量,可以直接在计算器上计算
(抄下来一定不要抄错啊!!这直接导致我此题挂了)(话说计算器不是可以复制吗)
code:
有点冗长,考场写的时候太慌了
#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef long long ll;
const int N1=1721424,fy=1461,st=4713,fhy=146097,N2=577737,st2=1582;
const int yr[]={366,365,365,365};
const int _yr[]={365,365,365,366};
const int mon1[]={31,28,31,30,31,30,31,31,30,31,30,31};
const int mon2[]={31,29,31,30,31,30,31,31,30,31,30,31};
inline void solve1(int x)
{
int z=x/fy,d=x%fy,m=1;
z<<=2;
for(int i=0;i<4;++i)
if(d>yr[i])d-=yr[i],++z;
else break;
z=st-z;
if(z%4!=1)
{
for(int i=0;i<12;++i)
if(d>mon1[i])d-=mon1[i],++m;
else break;
}
else
{
for(int i=0;i<12;++i)
if(d>mon2[i])d-=mon2[i],++m;
else break;
}
if(!d)d=31,m=12,++z;
printf("%lld %lld %lld BC\n",d,m,z);
}
inline void solve3(int x)
{
if(x<=17){printf("%lld 10 1582\n",15+x-1);return;}
x-=17;
if(x<=61)
{
if(x<=30){printf("%lld 11 1582\n",x);return;}
else {printf("%lld 12 1582\n",x-30);return;}
}
x-=61;
if(x<=6575)
{
int z=1583,m=1;
for(int i=1583;i<=1600;++i,++z)
{
if(i%4){if(x>365)x-=365;else break;}
else {if(x>366)x-=366;else break;}
}
if(z%4!=0)
{
for(int i=0;i<12;++i)
if(x>mon1[i])x-=mon1[i],++m;
else break;
}
else
{
for(int i=0;i<12;++i)
if(x>mon2[i])x-=mon2[i],++m;
else break;
}
if(!x)x=31,m=12,--z;
printf("%lld %lld %lld\n",x,m,z);return;
}
x-=6575;
int z=x/fhy,d=x%fhy,m=1;
z*=400;
for(int i=1;i<=400;++i,++z)
{
if(i%4){if(d>365)d-=365;else break;}
else if(i%100==0&&i%400!=0){if(d>365)d-=365;else break;}
else {if(d>366)d-=366;else break;}
}++z;z+=1600;
if(z%4||(z%100==0&&z%400!=0))
{
for(int i=0;i<12;++i)
if(d>mon1[i])d-=mon1[i],++m;
else break;
}
else
{
for(int i=0;i<12;++i)
if(d>mon2[i])d-=mon2[i],++m;
else break;
}
if(!d)d=31,m=12,--z;
printf("%lld %lld %lld\n",d,m,z);
}
inline void solve2(int x)
{
if(x>N2)return solve3(x-N2);
int z=x/fy,d=x%fy,m=1;
z<<=2;
for(int i=0;i<4;++i)
if(d>_yr[i])d-=_yr[i],++z;
else break;++z;
if(z%4!=0)
{
for(int i=0;i<12;++i)
if(d>mon1[i])d-=mon1[i],++m;
else break;
}
else
{
for(int i=0;i<12;++i)
if(d>mon2[i])d-=mon2[i],++m;
else break;
}
if(!d)d=31,m=12,--z;
printf("%lld %lld %lld\n",d,m,z);
}
int q,x;
signed main()
{
freopen("julian.in","r",stdin);
freopen("julian.out","w",stdout);
scanf("%lld",&q);
while(q--)
{
scanf("%lld",&x);++x;
if(x<=N1)solve1(x);
else solve2(x-N1);
}
return 0;
}
NO PAIN NO GAIN