CSP 2020 T1 儒略日

description

solution:

十分清新的大模拟题(大家都写得十分愉快吧)
话说解法并不复杂,大概分为以下几部分

  • 公元前
  • 公元后到\(1582.10.4\)
  • \(1582.10.15\)到无限的将来

首先容易知道确定了年份后日期计算十分容易
对于四年一闰的情况(即\(1582.10.4\)以前),判断位于哪一个四年,再判断具体在那一年
对于百年不闰四百年再闰的情况(即\(1582.10.15\)以后),判断位于哪一个四百年,再判断具体在那一年(可以直接暴力枚举判断)
其实就这么多了
特别地,对于我自己的程序要特判某些特定年份的\(12.31\),可能是写得太丑了
p.s.会遇到一大堆常量,可以直接在计算器上计算
(抄下来一定不要抄错啊!!这直接导致我此题挂了)(话说计算器不是可以复制吗)

code:

有点冗长,考场写的时候太慌了

#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef long long ll;
const int N1=1721424,fy=1461,st=4713,fhy=146097,N2=577737,st2=1582;
const int yr[]={366,365,365,365};
const int _yr[]={365,365,365,366};
const int mon1[]={31,28,31,30,31,30,31,31,30,31,30,31};
const int mon2[]={31,29,31,30,31,30,31,31,30,31,30,31};
inline void solve1(int x)
{
	int z=x/fy,d=x%fy,m=1;
	z<<=2;
	for(int i=0;i<4;++i)
		if(d>yr[i])d-=yr[i],++z;
		else break;
	z=st-z;
	if(z%4!=1)
	{
		for(int i=0;i<12;++i)
			if(d>mon1[i])d-=mon1[i],++m;
			else break;
	}
	else
	{
		for(int i=0;i<12;++i)
			if(d>mon2[i])d-=mon2[i],++m;
			else break;
	}
	if(!d)d=31,m=12,++z;
	printf("%lld %lld %lld BC\n",d,m,z);
}
inline void solve3(int x)
{
	if(x<=17){printf("%lld 10 1582\n",15+x-1);return;}
	x-=17;
	if(x<=61)
	{
		if(x<=30){printf("%lld 11 1582\n",x);return;}
		else {printf("%lld 12 1582\n",x-30);return;}
	}
	x-=61;
	if(x<=6575)
	{
		int z=1583,m=1;
		for(int i=1583;i<=1600;++i,++z)
		{
			if(i%4){if(x>365)x-=365;else break;}
			else {if(x>366)x-=366;else break;}
		}
		if(z%4!=0)
		{
			for(int i=0;i<12;++i)
				if(x>mon1[i])x-=mon1[i],++m;
				else break;
		}
		else
		{
			for(int i=0;i<12;++i)
				if(x>mon2[i])x-=mon2[i],++m;
				else break;
		}
		if(!x)x=31,m=12,--z;
		printf("%lld %lld %lld\n",x,m,z);return;
	}
	x-=6575;
	int z=x/fhy,d=x%fhy,m=1;
	z*=400;
	for(int i=1;i<=400;++i,++z)
	{
		if(i%4){if(d>365)d-=365;else break;}
		else if(i%100==0&&i%400!=0){if(d>365)d-=365;else break;}
		else {if(d>366)d-=366;else break;}
	}++z;z+=1600;
	if(z%4||(z%100==0&&z%400!=0))
	{
		for(int i=0;i<12;++i)
			if(d>mon1[i])d-=mon1[i],++m;
			else break;
	}
	else
	{
		for(int i=0;i<12;++i)
			if(d>mon2[i])d-=mon2[i],++m;
			else break;
	}
	if(!d)d=31,m=12,--z;
	printf("%lld %lld %lld\n",d,m,z);
}
inline void solve2(int x)
{
	if(x>N2)return solve3(x-N2);
	int z=x/fy,d=x%fy,m=1;
	z<<=2;
	for(int i=0;i<4;++i)
		if(d>_yr[i])d-=_yr[i],++z;
		else break;++z;
	if(z%4!=0)
	{
		for(int i=0;i<12;++i)
			if(d>mon1[i])d-=mon1[i],++m;
			else break;
	}
	else
	{
		for(int i=0;i<12;++i)
			if(d>mon2[i])d-=mon2[i],++m;
			else break;
	}
	if(!d)d=31,m=12,--z;
	printf("%lld %lld %lld\n",d,m,z);
}
int q,x;
signed main()
{
	freopen("julian.in","r",stdin);
	freopen("julian.out","w",stdout);
	scanf("%lld",&q);
	while(q--)
	{
		scanf("%lld",&x);++x;
		if(x<=N1)solve1(x);
		else solve2(x-N1);
	}
	return 0;
}
posted @ 2020-11-09 20:33  BILL666  阅读(141)  评论(0编辑  收藏  举报