CSP-S2 儒略日 题解

VenusM1nT

2020-11-09 12:33:40

Personal

对于公元前的,先分别以 $1000$,$100$ 和 $4$ 为位长跳到公元前 $-4$ 年,然后从公元前 $-4$ 年特判至公元 $1$ 年,然后以 $100$ 为位长跳到公元 $1501$ 年,特判是否在 $1501 - 1600$ 这个区间内,如果是的话,以 $4$ 年为周期往后跳,在 $1582$ 年停一下,如果不在 $1582$ 年内则继续往后跳,否则对这一年进行特殊处理。然后从 $1601$ 年分别以 $10^8 - 10^4$ 为周期往后跳,到 $10^3$ 的时候需要特判 $2000,4000...$ 的情况,然后以 $100$ 为周期,需要特判 $400,800$ 的情况,最后以 $4$ 年为周期往后跳。 至于算具体日期就没什么好说的了。 ```cpp #include<bits/stdc++.h> #define inl inline #define int long long using namespace std; int Y,M,D,mon[20]={0,31,28,31,30,31,30,31,31,30,31,30,31}; template <typename T> inl void Read(T &x) { x=0; int fu=1; char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') fu=-1; for(;isdigit(ch);ch=getchar()) x=x*10+ch-48; x*=fu; } inl bool isrun(int x) { if((!(x%4) && x%100) || !(x%400)) return 1; else return 0; } inl void Solve1(int x)//1582 ÄêÌØÊâ´¦Àí { if(M==1 && x>=mon[M]) x-=mon[M],M++; if(M==2 && x>=mon[M]) x-=mon[M],M++; if(M<=2) { D=x+1; return; } while(x>=mon[M] && M<10) x-=mon[M],M++; if(M==10) { if(x>=21) x-=21,M++; else { if(x<=3) { D=x+1; return; } else { D=x+11; return; } } } while(x>=mon[M]) x-=mon[M],M++; D=x+1; } inl void Solve2(int x) { if(x>=mon[M]) x-=mon[M],M++; if(M==2) { if((Y<=1582 && !(Y%4)) || (Y>1582 && isrun(Y))) { if(x>=29) x-=29,M++; } else if(x>=28) x-=28,M++; } if(M<=2) { D=x+1; return; } while(x>=mon[M]) x-=mon[M],M++; D=x+1; } inl void Solve3(int x)// - { if(x>=mon[M]) x-=mon[M],M++; if(M==2 && (abs(Y)%4==1) && x>=29) M++,x-=29; else if(M==2 && (abs(Y)%4!=1) && x>=28) M++,x-=28; if(M<=2) { D=x+1; return; } while(x>=mon[M]) x-=mon[M],M++; D=x+1; } signed main() { int Time; Read(Time); while(Time--) { int n,d; Read(n); Y=-4713; M=1; D=1; d=366*250+365*750; while(n>=d && Y<-1000) Y+=1000,n-=d; d=366*25+365*75; while(n>=d && Y<-100) Y+=100,n-=d; d=365*3+366; while(n>=d && Y<-4) { n-=d; Y+=4; } if((abs(Y)%4==1) && n>=366 && Y<-4) Y++,n-=366; else if((abs(Y)%4!=1) && n>=365 && Y<-4) Y++,n-=365; if((abs(Y)%4==1) && n>=366 && Y<-4) Y++,n-=366; else if((abs(Y)%4!=1) && n>=365 && Y<-4) Y++,n-=365; if((abs(Y)%4==1) && n>=366 && Y<-4) Y++,n-=366; else if((abs(Y)%4!=1) && n>=365 && Y<-4) Y++,n-=365; if((abs(Y)%4==1) && n>=366 && Y<-4) Y++,n-=366; else if((abs(Y)%4!=1) && n>=365 && Y<-4) Y++,n-=365; if((abs(Y)%4==1 && n<366) || (abs(Y)%4!=-1 && n<365)) { Solve3(n); printf("%lld %lld %lld BC\n",D,M,-Y); continue; } //printf(" - : %lld\n",Y); if(Y==-4 && n>=365) Y++,n-=365; if(Y==-3 && n>=365) Y++,n-=365; if(Y==-2 && n>=365) Y++,n-=365; if(Y==-1 && n>=366) Y=1,n-=366; if(Y<0) { if((abs(Y)%4==1 && n<366) || (abs(Y)%4!=-1 && n<365)) { Solve3(n); printf("%lld %lld %lld BC\n",D,M,-Y); continue; } } else { if(n<365) { Solve2(n); printf("%lld %lld %lld\n",D,M,Y); continue; } } //------------------------ d=365*75+366*25; while(n>=d && Y<1501) { n-=d; Y+=100; } if(Y<1500) { d=365*3+366; while(n>=d) Y+=4,n-=d; if(!(Y%4) && n>=366) Y++,n-=366; else if((Y%4) && n>=365) Y++,n-=365; if(!(Y%4) && n>=366) Y++,n-=366; else if((Y%4) && n>=365) Y++,n-=365; if(!(Y%4) && n>=366) Y++,n-=366; else if((Y%4) && n>=365) Y++,n-=365; if(!(Y%4) && n>=366) Y++,n-=366; else if((Y%4) && n>=365) Y++,n-=365; Solve2(n); printf("%lld %lld %lld\n",D,M,Y); continue; } d=365*75+366*25-10; if(n<=d)//Í£ÁôÔÚ 1501.1.1 ~ 1601.1.1 ÖÐ { d=365*3+366; while(n>=d && Y<1580) Y+=4,n-=d; //printf(" $ : %lld %lld\n",Y,n); //×î¶àÍ£ÁôÔÚ 1581.1.1 if(n<365) { Solve2(n); printf("%lld %lld %lld\n",D,M,Y); continue; } else if(Y==1581) { //puts("fuckccf"); n-=365; Y=1582; if(n<355) { Solve1(n); printf("%lld %lld %lld\n",D,M,Y); continue; } else n-=355,Y=1583; } d=365*3+366; while(n>=d) Y+=4,n-=d; if(isrun(Y) && n>=366) Y++,n-=366; else if(!isrun(Y) && n>=365) Y++,n-=365; if(isrun(Y) && n>=366) Y++,n-=366; else if(!isrun(Y) && n>=365) Y++,n-=365; if(isrun(Y) && n>=366) Y++,n-=366; else if(!isrun(Y) && n>=365) Y++,n-=365; if(isrun(Y) && n>=366) Y++,n-=366; else if(!isrun(Y) && n>=365) Y++,n-=365; //if(Y==1593) printf(" $ : %lld %lld\n",Y,n); Solve2(n); printf("%lld %lld %lld\n",D,M,Y); continue; } d=365*75+366*25-10; Y=1601; n-=d; //--------------------- //ÒÔÉÏΪС³ß¶È£¬ÏÂΪ´ó³ß¶È d=365ll*75750000ll+366ll*24250000ll;// 1e8 while(n>=d) Y+=1e8,n-=d; d=365ll*7575000ll+366ll*2425000ll;// 1e7 while(n>=d) Y+=1e7,n-=d; d=365ll*757500ll+366ll*242500ll;// 1e6 while(n>=d) Y+=1e6,n-=d; d=365*75750+366*24250;// 1e5 while(n>=d) Y+=1e5,n-=d; d=365*7575+366*2425;// 1e4 while(n>=d) Y+=1e4,n-=d; if((Y+1000-1)%400==0) d=757*365+243*366; else d=758*365+242*366; if(n>=d) n-=d,Y+=1000; if((Y+1000-1)%400==0) d=757*365+243*366; else d=758*365+242*366; if(n>=d) n-=d,Y+=1000; if((Y+1000-1)%400==0) d=757*365+243*366; else d=758*365+242*366; if(n>=d) n-=d,Y+=1000; if((Y+1000-1)%400==0) d=757*365+243*366; else d=758*365+242*366; if(n>=d) n-=d,Y+=1000; if((Y+1000-1)%400==0) d=757*365+243*366; else d=758*365+242*366; if(n>=d) n-=d,Y+=1000; if((Y+1000-1)%400==0) d=757*365+243*366; else d=758*365+242*366; if(n>=d) n-=d,Y+=1000; if((Y+1000-1)%400==0) d=757*365+243*366; else d=758*365+242*366; if(n>=d) n-=d,Y+=1000; if((Y+1000-1)%400==0) d=757*365+243*366; else d=758*365+242*366; if(n>=d) n-=d,Y+=1000; if((Y+1000-1)%400==0) d=757*365+243*366; else d=758*365+242*366; if(n>=d) n-=d,Y+=1000; if((Y+1000-1)%400==0) d=757*365+243*366; else d=758*365+242*366; if(n>=d) n-=d,Y+=1000; if((Y+100-1)%400==0) d=75*365+25*366; else d=76*365+24*366; if(n>=d) n-=d,Y+=100; if((Y+100-1)%400==0) d=75*365+25*366; else d=76*365+24*366; if(n>=d) n-=d,Y+=100; if((Y+100-1)%400==0) d=75*365+25*366; else d=76*365+24*366; if(n>=d) n-=d,Y+=100; if((Y+100-1)%400==0) d=75*365+25*366; else d=76*365+24*366; if(n>=d) n-=d,Y+=100; if((Y+100-1)%400==0) d=75*365+25*366; else d=76*365+24*366; if(n>=d) n-=d,Y+=100; if((Y+100-1)%400==0) d=75*365+25*366; else d=76*365+24*366; if(n>=d) n-=d,Y+=100; if((Y+100-1)%400==0) d=75*365+25*366; else d=76*365+24*366; if(n>=d) n-=d,Y+=100; if((Y+100-1)%400==0) d=75*365+25*366; else d=76*365+24*366; if(n>=d) n-=d,Y+=100; if((Y+100-1)%400==0) d=75*365+25*366; else d=76*365+24*366; if(n>=d) n-=d,Y+=100; if((Y+100-1)%400==0) d=75*365+25*366; else d=76*365+24*366; if(n>=d) n-=d,Y+=100; //printf(" $ : %lld - %lld\n",Y,n); d=365*3+366; while(n>=d) Y+=4,n-=d; if(isrun(Y) && n>=366) Y++,n-=366; else if(!isrun(Y) && n>=365) Y++,n-=365; if(isrun(Y) && n>=366) Y++,n-=366; else if(!isrun(Y) && n>=365) Y++,n-=365; if(isrun(Y) && n>=366) Y++,n-=366; else if(!isrun(Y) && n>=365) Y++,n-=365; if(isrun(Y) && n>=366) Y++,n-=366; else if(!isrun(Y) && n>=365) Y++,n-=365; if(Y>0) Solve2(n); else Solve3(n); if(Y>0) printf("%lld %lld %lld\n",D,M,Y); else printf("%lld %lld %lld BC\n",D,M,-Y); } return 0; } ```