P7075 儒略日(2020CSP-S T1)

考试的时候就一个地方写挂了啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊,要不然就完成了场切大模拟的壮举

思路

有什么思路啊,就模拟啊。。。首先发现1582年之前是白给,我一开始决定整个题都使用取模操作。但是我发现公元前4713年1月1日是第0天,也就是这一天不算在儒略日内,但是公元1年1月1日是算的,这就导致它们之间的代码有很多细节都不一样,我也就是这里写挂了。其实公元前取模操作比较好写,好吧其实差不多的,但我考场上就是取模取挂了,本来应该是1111年12月31号,我取模一个细节炸了,输出了1115年12月31号。痛失60pts。但是无所谓,毕竟这次考试并不重要。所以我改成公元后一年一年地跑,就算全是极限数据,也才是1e8(我相信i7的实力),是可以跑的,况且出题人不可能构造这样的数据,那1e5组不可能都是1582年之前的,显然1582年之后更恶心。这样暴力跑完之后,1582年之后必须取模了,不然复杂度炸裂。注意到闰年是400年一个周期,也就是说我们可以算出400年一共多少天,然后对它取模,就可以将年份确定在400年的一个区间里,在这个区间内再一年一年跑,时间复杂度最差是\(O(400Q)\),对i7来说小菜一碟,而且不可能这么精准地卡到我最差时间复杂度。当然,为了便于实现,我特判了1582年到1582年之间的部分,从1583年1月1日开始算,会更加方便。

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<ctime>
#include<map>
using namespace std;
typedef long long ll;
inline ll read(){
	ll x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
ll Q,r,ri,yue,nian;
ll run[15]={0,31,29,31,30,31,30,31,31,30,31,30,31};
ll ping[15]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int main()
{
	Q=read();
	while(Q--){
		r=read();
		if(r<=1721423){//公元前
			ll sum1=r/1461,sum2=r%1461+1;
			nian=4713-sum1*4;//取模操作,细节手玩即可
			for(ll i=nian;i;i--){
				if(nian%4==1){
					if(sum2<=366){
						break;
					}
					else{
						sum2-=366;
						nian--;
					}
				}
				else{
					if(sum2<=365){
						break;
					}
					else{
						sum2-=365;
						nian--;
					}
				}
			}
			if(nian%4==1){
				for(ll i=1;i<=12;i++){
					if(sum2<=run[i]){
						yue=i;
						ri=sum2;
						break;
					}
					else{
						sum2-=run[i];
					}
				}
			}
			else{
				for(ll i=1;i<=12;i++){
					if(sum2<=ping[i]){
						yue=i;
						ri=sum2;
						break;
					}
					else{
						sum2-=ping[i];
					}
				}
			}//确定区间后一年一年跑
			printf("%lld %lld %lld BC\n",ri,yue,nian);
			continue;
		} 
		else{
			r-=1721423;//减去公元前的天数
			if(r<=577737){//1582年之前
				nian=1;
				ll sum2=r;
				for(int i=nian;i;i++){//直接暴力枚举
					if(i%4==0){
						if(sum2<=366){
							break;
						}
						else{
							sum2-=366;
							nian++;
						}
					}
					else{
						if(sum2<=365){
							break;
						}
						else{
							sum2-=365;
							nian++;
						}	
					}
				}
				if(nian%4==0){
					for(int i=1;i<=12;i++){
						if(sum2<=run[i]){
							yue=i;
							ri=sum2;
							break;
						}
						else{
							sum2-=run[i];
						}
					}
				}
				else{
					for(int i=1;i<=12;i++){
						if(sum2<=ping[i]){
							yue=i;
							ri=sum2;
							break;
						}
						else{
							sum2-=ping[i];
						}
					}
				}
				printf("%lld %lld %lld\n",ri,yue,nian);
			}
			else{//1582年之后
				r-=577737;
				nian=1582;
				if(r<=78){
					if(r<=78&&r>47){
						ri=r-47;
						yue=12;
					}
					if(r<=47&&r>17){
						ri=r-17;
						yue=11;
					}
					if(r<=17&&r>0){
						ri=r+14;
						yue=10;
					}
					printf("%lld %lld %lld\n",ri,yue,nian);
					continue;
				}//特判到1583年
				nian=1583;
				r-=78;
				ll sum1=r/146097,sum2=r%146097;
				nian+=sum1*400;
				if(sum2==0){
					nian-=400;
					sum2=146097;
				}
				for(ll i=nian;i;i++){
					if(nian%4==0){
						if(nian%100!=0||nian%400==0){
							if(sum2<=366){
								break;
							}
							else{
								sum2-=366;
								nian++;
							}
						} 
						else{
							if(sum2<=365){
								break;
							}
							else{
								sum2-=365;
								nian++;
							}
						}
					}
					else{
						if(sum2<=365){
							break;
						}
						else{
							sum2-=365;
							nian++;
						}
					}
				}
				if(nian%4==0){
					if((nian%100!=0)||(nian%400==0)){
						for(ll i=1;i<=12;i++){
							if(sum2<=run[i]){
								yue=i;
								ri=sum2;
								break;
							}
							else{
								sum2-=run[i];
							}
						}
					} 
					else{
						for(ll i=1;i<=12;i++){
							if(sum2<=ping[i]){
								yue=i;
								ri=sum2;
								break;
							}
							else{
								sum2-=ping[i];
							}
						}
					}
				}
				else{
					for(ll i=1;i<=12;i++){
						if(sum2<=ping[i]){
							yue=i;
							ri=sum2;
							break;
						}
						else{
							sum2-=ping[i];
						}
					}
				}
				printf("%lld %lld %lld\n",ri,yue,nian);
			}
		}
	}
	return 0;
}

\(upd:取模板de出bug了,不过我NOIp也炸了。。。\)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<ctime>
#include<map>
using namespace std;
typedef long long ll;
inline ll read(){
	ll x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
ll Q,r,ri,yue,nian;
ll run[15]={0,31,29,31,30,31,30,31,31,30,31,30,31};
ll ping[15]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int main()
{
//	freopen("P7075_6.in","r",stdin);
//	freopen("julian3.out","w",stdout);
	Q=read();
	while(Q--){
		r=read();
		if(r<=1721423){
			ll sum1=r/1461,sum2=r%1461+1;
			nian=4713-sum1*4;
			for(ll i=nian;i;i--){
				if(nian%4==1){
					if(sum2<=366){
						break;
					}
					else{
						sum2-=366;
						nian--;
					}
				}
				else{
					if(sum2<=365){
						break;
					}
					else{
						sum2-=365;
						nian--;
					}
				}
			}
			if(nian%4==1){
				for(ll i=1;i<=12;i++){
					if(sum2<=run[i]){
						yue=i;
						ri=sum2;
						break;
					}
					else{
						sum2-=run[i];
					}
				}
			}
			else{
				for(ll i=1;i<=12;i++){
					if(sum2<=ping[i]){
						yue=i;
						ri=sum2;
						break;
					}
					else{
						sum2-=ping[i];
					}
				}
			}
			printf("%lld %lld %lld BC\n",ri,yue,nian);
			continue;
		} 
		else{
			r-=1721423;
			if(r<=577737){
				ll sum1=r/1461,sum2=r%1461;
				nian=sum1*4+1;
				if(sum2==0){
					nian-=4;
					sum2=1461;
				}
				for(int i=nian;i;i++){
					if(i%4==0){
						if(sum2<=366){
							break;
						}
						else{
							sum2-=366;
							nian++;
						}
					}
					else{
						if(sum2<=365){
							break;
						}
						else{
							sum2-=365;
							nian++;
						}	
					}
				}
				if(nian%4==0){
					for(int i=1;i<=12;i++){
						if(sum2<=run[i]){
							yue=i;
							ri=sum2;
							break;
						}
						else{
							sum2-=run[i];
						}
					}
				}
				else{
					for(int i=1;i<=12;i++){
						if(sum2<=ping[i]){
							yue=i;
							ri=sum2;
							break;
						}
						else{
							sum2-=ping[i];
						}
					}
				}
				printf("%lld %lld %lld\n",ri,yue,nian);
			}
			else{
				r-=577737;
				nian=1582;
				if(r<=78){
					if(r<=17){
						ri=r+14;
						yue=10;
					}
					if(r>17&&r<=47){
						ri=r-17;
						yue=11;
					}
					if(r>47&&r<=78){
						ri=r-47;
						yue=12;
					}
					printf("%lld %lld %lld\n",ri,yue,nian);
					continue;
				}
				nian=1583;
				r-=78;
				ll sum1=r/146097,sum2=r%146097;
				nian+=sum1*400;
				if(sum2==0){
					nian-=400;
					sum2=146097;
				}
				for(ll i=nian;i;i++){
					if(nian%4==0){
						if(nian%100!=0||nian%400==0){
							if(sum2<=366){
								break;
							}
							else{
								sum2-=366;
								nian++;
							}
						} 
						else{
							if(sum2<=365){
								break;
							}
							else{
								sum2-=365;
								nian++;
							}
						}
					}
					else{
						if(sum2<=365){
							break;
						}
						else{
							sum2-=365;
							nian++;
						}
					}
				}
				if(nian%4==0){
					if((nian%100!=0)||(nian%400==0)){
						for(ll i=1;i<=12;i++){
							if(sum2<=run[i]){
								yue=i;
								ri=sum2;
								break;
							}
							else{
								sum2-=run[i];
							}
						}
					} 
					else{
						for(ll i=1;i<=12;i++){
							if(sum2<=ping[i]){
								yue=i;
								ri=sum2;
								break;
							}
							else{
								sum2-=ping[i];
							}
						}
					}
				}
				else{
					for(ll i=1;i<=12;i++){
						if(sum2<=ping[i]){
							yue=i;
							ri=sum2;
							break;
						}
						else{
							sum2-=ping[i];
						}
					}
				}
				printf("%lld %lld %lld\n",ri,yue,nian);
			}
		}
	}
	return 0;
}
posted @ 2020-11-11 17:29  徐明拯  阅读(182)  评论(0编辑  收藏  举报