1 条题解
-
-1
按照题意模拟即可。
由于年代不同,闰年计算方式不同,而且中间还有删除的部分。所以我们分成四个部分处理:
-
公元前 4713 年 1 月 1 日至公元前 1 年 12 月 31 日。
-
公元 1 年 1 月 1 日至公元 1582 年 10 月 4 日。
-
公元 1582 年 10 月 15 日至公元 1582 年 12 月 31 日。
-
公元 1583 年 1 月 1 日至时间轴无穷远处。
我们预处理出平年/闰年的第 天的日期。然后对于每一部分,我们使用二分求出儒略日所在年份,然后会剩下一些天数,查表就行了。
代码细节较多,但理清思路后比较好实现。
#include<bits/stdc++.h> #define int long long using namespace std; inline int read() { int x=0,y=1; char e=getchar(); while(e<'0'||e>'9') { if(e=='-')y=-1; e=getchar(); } while(e>='0'&&e<='9') { x=(x<<1)+(x<<3)+(e-'0'); e=getchar(); } return x*y; } inline bool f29(int y,int op) { if(op==0) { //op=0 is julian calendar if((abs(y)-1)%4==0)return 1; return 0; } else if(op==1) { //op=1 is gregorian calendar if(y%400==0||(y%100!=0&&y%4==0))return 1; return 0; } else { if(y%4==0)return 1; return 0; } } pair<int,int> res[2][400]; //0 is ping year; 1 is run year int pmonth_cnt[]= {0,31,28,31,30,31,30,31,31,30,31,30,31}; int rmonth_cnt[]= {0,31,29,31,30,31,30,31,31,30,31,30,31}; signed main() { // freopen("julian.in","r",stdin); // freopen("julian.out","w",stdout); for(int i=1,tot=0; i<=12; ++i) { for(int j=1; j<=pmonth_cnt[i]; ++j) { res[0][++tot]= {i,j}; } } for(int i=1,tot=0; i<=12; ++i) { for(int j=1; j<=rmonth_cnt[i]; ++j) { res[1][++tot]= {i,j}; } } int T=read(); while(T--) { int n=read(); if(n<1721424) { // BCE 4713*365+1179 int l=1,r=4713,mid,ans=r; while(l<=r) { mid=(l+r)>>1; if((4713-mid)*365+(4713-mid+3)/4<=n) ans=mid,r=mid-1; else l=mid+1; } n-=(4713-ans)*365+(4713-ans+3)/4-1; cout<<res[f29(ans,0)][n].second<<" "<<res[f29(ans,0)][n].first<<" "<<ans<<" BC\n"; } else if(n<2299161) { // [1.1.1~1582.10.4] 1721424+1581*365+395+277 n-=1721424; int l=1,r=1582,mid,ans=1; while(l<=r) { mid=(l+r)>>1; if((mid-1)*365+(mid-1)/4<=n)ans=mid,l=mid+1; else r=mid-1; } n-=(ans-1)*365+(ans-1)/4-1; cout<<res[f29(ans,2)][n].second<<" "<<res[f29(ans,2)][n].first<<" "<<ans<<"\n"; } else if(n<2299239) { //1582.10.15~1582.12.31 n-=2299161; int i=10,j=15; while(n--) { if(j==pmonth_cnt[i])++i,j=1; else ++j; } cout<<j<<" "<<i<<" "<<"1582\n"; } else { //1583.1.1~inf n-=2299239; int l=1583,r=1000000000,mid,ans=r; while(l<=r) { mid=(l+r)>>1; if((mid-1583)*365+(mid-1583+2)/4-(mid-1583+82)/100+(mid-1583+382)/400<=n)ans=mid,l=mid+1; else r=mid-1; } n-=(ans-1583)*365+(ans-1583+2)/4-(ans-1583+82)/100+(ans-1583+382)/400-1; cout<<res[f29(ans,1)][n].second<<" "<<res[f29(ans,1)][n].first<<" "<<ans<<"\n"; } } return 0; } -
- 1
信息
- ID
- 462
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 8
- 标签
- (无)
- 递交数
- 15
- 已通过
- 6
- 上传者