Title: [CSP-S2020] Julian day - Valleyhttps://www.luogu.com.cn/problem/P7075
After reading the question, we can see that this question is a simulation question about time.
According to the meaning of the question:
- The time is divided into two periods: the Julian calendar from January 1, 4713 BC to October 4, 1582 ad (inclusive); October 15, 1582 The Gregorian calendar is the day after (including).
- October 5 (inclusive) to October 14 (inclusive) in 1582: No, these dates were deleted, and October 15 after October 4 of that year.
- Gregorian calendar rule: January of each year thirty-one Day, February twenty-eight Days or twenty-nine Days, March thirty-one Days, April thirty Days, may thirty-one Days, June thirty Days, July thirty-one Days, August thirty-one Days, September thirty Days and October thirty-one Days, November thirty Days, December thirty-one Oh, my God. Among them, February of leap year is twenty-nine Days, weekdays twenty-eight Oh, my God. What was it then four hundred Multiple of, or date year is four Multiple of, but not one hundred The year is a leap year.
- Julian day rule: the number of days per month is the same as that in the Gregorian calendar, but as long as the year is four The multiple of is leap year.
- Year 0 does not exist, that is, the next year after year 1 B.C. is year 1 A.D. Therefore, years such as 1 BC, 5 BC, 9 BC, 13 BC... Should be regarded as leap years. Note that the year from A.D. 1 to A.D. 1582 is four The multiple of is leap year, i.e. ad 4, ad 8... And so on should be regarded as leap year. After A.D. 1589, it is applicable to the Gregorian calendar four hundred Multiple of, or date year is four Multiple of, but not one hundred The year is a leap year.
First, we can observe the data range of the topic at this time. We can't calculate day by day or year by year. According to the meaning of the topic analyzed above, before 1582, the Julian calendar was applicable. Every multiple of 4 is a leap year, that is, a cycle of 4 years. We can calculate the total number of cycles by division. Through our calculation, It is easy to calculate the number of days in a leap year cycle of the Julian calendar, that is, the number of days in three ordinary years and one leap year: 3 * 365 + 366 = 1461 days. After 1582, it is applicable to the Gregorian calendar. There is a cycle every 400 years, that is, 303 ordinary years and 97 leap years: 303 * 365 + 97 * 366 = 146097 days.
The number of days on October 4, 1582 is calculated as follows:
From 4713.1.1 to 1582.10.4 B.C., 4712 + 1582 = 6292 years.
Among them, there were 1179 leap years and 1178 * 3 ordinary years from 1 BC to 4713 BC. (because 1 BC, 5 BC ·································································································································.
From AD 1 to ad 1582, there were 395 leap years and 1187 ordinary years (including 1582). Therefore, the number of days is 395 * 366 + 1186 * 365 + October 4 of ordinary year = 577737 days.
To sum up: 2299160 days from 4713.1.1 to 1582.10.4 B.C. Take this number of days as the dividing line to divide the Julian calendar and the Gregorian calendar.
If the number of days < 2299160, it shall be calculated according to the Julian calendar. According to the previous analysis, we can know that there is a cycle every 4 years, and a cycle is 1461 days, so we can quickly calculate the cycle of the given days. The specific operations are as follows:
years=n/1461*4-4713;//years is the answer year, - 4713 is because BC n%=1461;
If the number of days > 2299160, the Gregorian calendar is used for calculation every 400 years. The specific operations are as follows:
n-=2159351; //Subtract the number of days on January 1, 1200, because there is a cycle every 400 years from year 1 A.D years=(n/N)*400+1200; //Add the minus 1200 years. n%=N;
After the period calculation, the Julian and Gregorian calendars need to calculate the year in the period. The specific operations are as follows:
First, you need to judge whether the year is a leap year.
1. Leap year judgment of Julian calendar:
bool pd(int y){ if((y%4==0&&y>0)||y%4==-1)return 1; else return 0; }
2. Leap year judgment of Gregorian calendar:
bool pd1(int y){ if(y%400==0||((y%4==0)&&(y%100!=0)))return 1; else return 0; }
Year calculation:
1. Julian calendar:
if(years>=0) years++;//Because there is no year 0, it takes + + to 1 year to meet year 0. while(n>=365){ if(years==0) years++; if(pd(years)&&n>=366){ //pd() this function determines whether it is a leap year. If it is, it returns 1 instead of 0 n-=366; years+=1; } else if(!pd(years)&&n>=365){ n-=365; years+=1; } else break; } if(years==0) years++;
2. Gregory Calendar
while(n>=365){ if(pd1(years)&&n>=366){//pd1() is to judge whether it is a leap year. If yes, it returns 1 instead of 0 n-=366; years+=1; } else if(!pd1(years)&&n>=365){ n-=365; years+=1; } else break; }
After the year is calculated, the month and day need to be calculated. Because the Julian calendar and Gregorian calendar judge leap years in different ways, I wrote two functions to solve them respectively.
1. Julian calendar
int find_mon(long long years,long long x){ int mon=1; if(pd(years)){ int i=1; while(x>=r[i]){ x-=r[i];i++; mon++; } }else{ int i=1; while(x>=p[i]){ x-=p[i]; i++; mon++; } } days=x; return mon; }
2. Gregory Calendar
int find_mon1(long long years,long long x){ int mon=1; if(pd1(years)){ int i=1; while(x>=r[i]){ x-=r[i];i++; mon++; } }else{ int i=1; while(x>=p[i]){ x-=p[i];i++; mon++; } } days=x; return mon; }
Then this question can be AC.
The AC code is as follows:
#include<iostream> #include<cmath> #include<cstdio> using namespace std; int q; long long days; int N=146097; int r[13]={0,31,29,31,30,31,30,31,31,30,31,30,31}; int p[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; bool pd(int y){ if((y%4==0&&y>0)||y%4==-1)return 1; else return 0; } bool pd1(int y){ if(y%400==0||((y%4==0)&&(y%100!=0)))return 1; else return 0; } int find_mon(long long years,long long x){ int mon=1; if(pd(years)){ int i=1; while(x>=r[i]){ x-=r[i];i++; mon++; } }else{ int i=1; while(x>=p[i]){ x-=p[i]; i++; mon++; } } days=x; return mon; } int find_mon1(long long years,long long x){ int mon=1; if(pd1(years)){ int i=1; while(x>=r[i]){ x-=r[i];i++; mon++; } }else{ int i=1; while(x>=p[i]){ x-=p[i];i++; mon++; } } days=x; return mon; } int main(){ //freopen("P7075_5.in","r",stdin); //freopen("julian3.out","w",stdout); cin>>q; while(q--){ long long n; long long years,months; cin>>n; if(n>2299160){//Gregory 1582.10.15 n-=2159351; years=(n/N)*400+1200; n%=N; while(n>=365){ if(pd1(years)&&n>=366){ n-=366; years+=1; } else if(!pd1(years)&&n>=365){ n-=365; years+=1; } else break; } months=find_mon1(years,n); } else{//Before 1582.10.4 Julian calendar years=n/1461*4-4713; n%=1461; if(years>=0) years++; while(n>=365){ if(years==0) years++; if(pd(years)&&n>=366){ n-=366; years+=1; } else if(!pd(years)&&n>=365){ n-=365; years+=1; } else break; } if(years==0) years++; months=find_mon(years,n); } if(years<0) cout<<days+1<<" "<<months<<" "<<abs(years)<<" BC"<<endl; else cout<<days+1<<" "<<months<<" "<<years<<endl; } return 0; }