题解
2025-10-19 18:44:58
发布于:浙江
1阅读
0回复
0点赞
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ch() getchar()
#define pc(x) putchar(x)
using namespace std;
template<typename T>void read(T&x){
static int f;static char c;
for(c=ch(),f=1;c<'0'||c>'9';c=ch())if(c=='-')f=-f;
for(x=0;c>='0'&&c<='9';c=ch())x=x*10+(c&15);x*=f;
}
template<typename T>void write(T x){
static int q[64];int cnt=0;
if(x==0)return pc('0'),void();
if(x<0)pc('-'),x=-x;
while(x)q[cnt++]=x%10,x/=10;
while(cnt--)pc(q[cnt]+'0');
}
const int data0[13]={0,31,28,31,30,31,30,31,31,30,31,30,31},//平年
data1[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};//闰年
void getyear(void){//这个是用来获取平年一年天数的,也就是 365 天
int tmp=0;
for(int i=1;i<=12;++i)
tmp+=data0[i];
printf("year:%d\n",tmp);
}
void getsum(void){
int sum=0;
for(int i=4713;i>=1;--i)
sum+=365+(i%4==1);
//reach 1.1.1
printf("reach 1.1.1:%d\n",sum);
for(int i=1;i<=1581;++i)
sum+=365+(i%4==0);
//reach 1582.1.1
for(int i=1;i<=9;++i)
sum+=data0[i];
//reach 1582.10.1
sum+=4;
//reach 1582.10.5 1582.10.15
printf("reach 1582.10.15:%d\n",sum);
sum+=17;
//reach 1582.11.1
for(int i=11;i<=12;++i)
sum+=data0[i];
//reach 1583.1.1
printf("reach 1583.1.1:%d\n",sum);
}
const int R0=1721424,R1=2299161,R2=2299239;
long long getyear0(long long r){
// r 表示从公元前 4713 年 1 月 1 日开始还需要经过多少天
long long L=0,R=4712;
while(L<R){
long long M=(L+R+1)>>1;
long long D=(M+3)/4+M*365;
if(D>r)R=M-1;else L=M;
}
return L;
}
long long getyear1(long long r){
// r 表示从公元 1 年 1 月 1 日开始还需要经过多少天
long long L=0,R=1581;
while(L<R){
long long M=(L+R+1)>>1;
long long D=M/4+M*365;
if(D>r)R=M-1;else L=M;
}
return L;
}
long long getyear2(long long r){
// r 表示从公元 1583 年 1 月 1 日开始还需要经过多少天
long long L=0,R=1000000000;
while(L<R){
long long M=(L+R+1)>>1;
long long D=(M+2)/4-(M+82)/100+(M+382)/400+M*365;
if(D>r)R=M-1;else L=M;
}
return L;
}
void work(void){
int q;read(q);
while(q--){
long long r;read(r);
if(r<R0){
//before 1.1.1
long long Y=getyear0(r);
r-=(Y+3)/4+Y*365;++r;
//这里 ++r 是因为此时已经是 1 月 1 日了,而后面 r 还需要用来计算天数,所以 r 初始就是 1
Y=4713-Y;long long M=1;
// Y 是年份, M 是月份
if(Y%4!=1){//平年
while(r>data0[M])
r-=data0[M],++M;
}
else{//闰年
while(r>data1[M])
r-=data1[M],++M;
}
write(r),pc(' '),write(M),pc(' '),write(Y),pc(' ');
pc('B'),pc('C');
}
else if(r>=R0&&r<R1){
//before 1582.10.5 1582.10.15
r-=R0;
long long Y=getyear1(r);
r-=Y/4+Y*365;++r;
//这里 ++r 是因为此时已经是 1 月 1 日了,而后面 r 还需要用来计算天数,所以 r 初始就是 1
Y=Y+1;long long M=1;
// Y 是年份, M 是月份
if(Y%4!=0){//平年
while(r>data0[M])
r-=data0[M],++M;
}
else{//闰年
while(r>data1[M])
r-=data1[M],++M;
}
write(r),pc(' '),write(M),pc(' '),write(Y);
}
else if(r>=R1&&r<R2){
//before 1583.1.1
r-=R1;
if(r<17){
r+=15;//从 10 月 15 日开始算起
write(r),pc(' '),write(10),pc(' '),write(1582);
}
else{
r-=17;++r;
//这里 ++r 是因为此时已经是 1582 年 11 月 1 日了,而后面 r 还需要用来计算天数,所以 r 初始就是 1
long long M=11;
// M 是月份
while(r>data0[M])
r-=data0[M],++M;
write(r),pc(' '),write(M),pc(' '),write(1582);
}
}
else if(r>=R2){
r-=R2;
long long Y=getyear2(r);
r-=(Y+2)/4-(Y+82)/100+(Y+382)/400+Y*365;++r;
//这里 ++r 是因为此时已经是 1583 年 1 月 1 日了,而后面 r 还需要用来计算天数,所以 r 初始就是 1
Y+=1583;long long M=1;
// Y 是年份, M 是月份
if(Y%4!=0||(Y%100==0&&Y%400!=0)){
while(r>data0[M])
r-=data0[M],++M;
}
else{
while(r>data1[M])
r-=data1[M],++M;
}
write(r),pc(' '),write(M),pc(' '),write(Y);
}
pc('\n');
}
}
int main(){
// getsum();
work();
return 0;
}
这里空空如也







有帮助,赞一个