专栏文章
题解:P7075 [CSP-S2020] 儒略日
P7075题解参与者 5已保存评论 7
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 7 条
- 当前快照
- 1 份
- 快照标识符
- @miqlnwzc
- 此快照首次捕获于
- 2025/12/04 06:50 3 个月前
- 此快照最后确认于
- 2025/12/04 06:50 3 个月前
update:发现了一处错别字
题意
给出一个儒略日日期,需要我们将它转化成格里高利历(公历)日期。
推荐一个好用的小工具,可以帮助检验代码问题:儒略日数和日干支计算器,注意表格中的日期如果是公元前的话要减一,建议看中部的蓝字显示的日期。
推荐一个好用的小工具,可以帮助检验代码问题:儒略日数和日干支计算器,注意表格中的日期如果是公元前的话要减一,建议看中部的蓝字显示的日期。
思路
其实就是暴力模拟,但是需要注意不少要点,也可以说是坑点。
- 闰年的判断方式不同,在 及以前判断闰年只需要判断是否为 的倍数即可,但在 及以后,判断闰年的方法便变为需要满足年份是 的倍数或者年份是 的倍数且不是 的倍数。
- 当年份是公元前的年份时,因为没有公元零年,必须将年份先加一,再判断是否为 的倍数。
这样看来,这个题还是比较水的,但是当你打完下面给出的暴力后,会看到只有 分,并且还是超时了。
暴力 分代码:
#include <bits/stdc++.h>
#define int long long
#define rint register int
#define ll long long
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define bug puts("!!!====!!!=");
using namespace std;
int t,n,day,year,month,aly;
int date[2][13]={0,31,28,31,30,31,30,31,31,30,31,30,31,0,31,29,31,30,31,30,31,31,30,31,30,31};;
bool BC,flag,ru;
bool run(int x){
if(BC){
x++;
if(x%4==0){
return 1;
}
return 0;
}
if((x%400==0)||(x%4==0&&x%100!=0)||(x%4==0&&ru)){
return 1;
}
return 0;
}
signed main(){
BC=1;
BC=1;
cin>>t;
while(t--){
cin>>n;
BC=1;
ru=1;
year=-4713;
month=1;
day=1;
while(1){
if(year==1582){
ru=0;
}
if(!run(year)){
if(n>=355){
n-=355;
if(year!=1582){
n-=10;
if(n<0){
n+=365;
break;
}
}
year++;
if(year==0){
year++;
BC=0;
}
}
else{
break;
}
}
else{
if(n>=356){
n-=356;
if(year!=1582){
n-=10;
if(n<0){
n+=366;
break;
}
}
year++;
if(year==0){
year++;
BC=0;
}
}
else{
break;
}
}
}
flag=run(year);
while(n--){
day++;
if(day==date[flag][month]+1){
day=1;
month++;
}
if(year==1582&&month==10&&day==5){
day=15;
}
}
cout<<day<<' '<<month<<' '<<abs(year);
if(BC){
cout<<" BC";
}
cout<<'\n';
}
return 0;
}
那么此刻,很多人既不知道如何优化,又不想重写代码,诶,那么此时,我们会发现一个规律:在 年(既开始使用格里高利历)后,每 年为一个周期,那么我们选择 、、 来进行循环,只需要在循环时把减去每年的天数变成减去 、、 年的天数即可。
那么这样我们便得到了一段优化代码:
CPP那么这样我们便得到了一段优化代码:
while(n-29219400>0){
n-=29219400;
year+=80000;
}
while(n-2921940>0){
n-=2921940;
year+=8000;
}
while(n-292194>0){
n-=292194;
year+=800;
}
完整代码
#include <bits/stdc++.h>
#define int long long
#define rint register int
#define ll long long
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define bug puts("!!!====!!!=");
using namespace std;
int t,n,day,year,month,aly;
int date[2][13]={0,31,28,31,30,31,30,31,31,30,31,30,31,0,31,29,31,30,31,30,31,31,30,31,30,31};;
bool BC,flag,ru;
bool run(int x){
if(BC){
x++;
if(x%4==0){
return 1;
}
return 0;
}
if((x%400==0)||(x%4==0&&x%100!=0)||(x%4==0&&ru)){
return 1;
}
return 0;
}
signed main(){
BC=1;
BC=1;
cin>>t;
while(t--){
cin>>n;
BC=1;
ru=1;
year=-4713;
month=1;
day=1;
if(n>=1721424){
n-=1721424;
BC=0;
year=1;
}
while(1){
if(year==1582){
ru=0;
}
if(!run(year)){
if(n>=355){
n-=355;
if(year!=1582){
n-=10;
if(n<0){
n+=365;
break;
}
}
year++;
if(year==0){
year++;
BC=0;
}
}
else{
break;
}
}
else{
if(n>=356){
n-=356;
if(year!=1582){
n-=10;
if(n<0){
n+=366;
break;
}
}
year++;
if(year==0){
year++;
BC=0;
}
}
else{
break;
}
}
if(year==1583){
break;
}
}
while(n-29219400>0){
n-=29219400;
year+=80000;
}
while(n-2921940>0){
n-=2921940;
year+=8000;
}
while(n-292194>0){
n-=292194;
year+=800;
}
while(n-365>0){
n-=365;
if((year%4==0&&year%100!=0)||year%400==0){
n--;
}
year++;
}
flag=run(year);
while(n--){
day++;
if(day==date[flag][month]+1){
day=1;
month++;
if(month==13){
month=1;
year++;
flag=run(year);
}
}
if(year==1582&&month==10&&day==5){
day=15;
}
}
cout<<day<<' '<<month<<' '<<abs(year);
if(BC){
cout<<" BC";
}
cout<<'\n';
}
return 0;
}
相关推荐
评论
共 7 条评论,欢迎与作者交流。
正在加载评论...