CSP-S2 儒略日 题解
VenusM1nT
2020-11-09 12:33:40
对于公元前的,先分别以 $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;
}
```