儒略历
题目描述
在 1582 年之前,以 4 为倍数的年份为闰年。正常情况下,一年中一月到十二月的天数分别是 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 天。如果这年是闰年,那么二月则有 29 天。
但某位皇帝发现这么做其实不够准确,会造成误差,因此规定从 1582 年开始,以 4 为倍数的年份,除了以 100 为倍数且不为 400 的倍数年份,才是闰年。同时为了消除误差,规定 1582 年 10 月 4 日的下一天是 1582 年 10 月 15 日,中间的日期就当作不存在了。现在给出日期,计算这个日期到公元 1 年 1 月 1 日经过的天数。
输入描述
按照
日月年的格式输入数据,其中日是 1 到 31 之间的整数,月是三个大写字母,年是 1 到 9999 之间的整数。保证这个日期是合法且存在的。月份的大写字母:
- 1月:JAN
- 2月:FEB
- 3月:MAR
- 4月:APR
- 5月:MAY
- 6月:JUN
- 7月:JUL
- 8月:AUG
- 9月:SEP
- 10月:OCT
- 11月:NOV
- 12月:DEC
输出描述
输出一个整数表示答案
输入样例
4OCT1582
输出样例
577736
思路
判断两个日期的天数间隔时,可以先从年份开始推算,将年份较小的日期的年份的值去接近年份较大的日期的年份,即每次将年份加一,总天数的变化为增加那一年的总天数,年份相等后,开始比较月份的差距,同样让将月份较小的日期的月份的值去接近月份较大的日期的月份。日数同样如此。此题中由于日期中间有截断,所以可以将1582 年 10 月 4 日作为分界点分两种情况考虑。
示例代码
#include <algorithm>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <math.h>
#include <stdio.h>
#include <string.h>
using namespace std;
using ll = long long;
const int INF = 0X3F3F3F3F;
typedef struct DATE
{
int year;
int month;
int day;
} Date;
void swap(Date *pdate1, Date *pdate2) // 交换年份
{
Date tmp = *pdate1;
*pdate1 = *pdate2;
*pdate2 = tmp;
}
int dateCmp(Date date1, Date date2) // 判断那个日期更晚
{
if (date1.year < date2.year)
return -1;
else if (date1.year > date2.year)
return 1;
// 年份相同进行下面的判断
if (date1.month < date2.month)
return -1;
else if (date1.month > date2.month)
return 1;
// 月份相同进行下面的判断
if (date1.day < date2.day)
return -1;
else if (date1.day > date2.day)
return 1;
// 日期相同返回0
return 0;
}
int isLeap(int year) // 判断闰年
{
return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0 || (year % 4 == 0 && year < 1582);
}
int year_days(int year) // 返回年份对应天数
{
if (isLeap(year))
return 366;
else
return 365;
}
int month_days(int year, int m) // 判断月份对应天数
{
int days = 0;
if (m < 1 || m > 12)
exit(-1);
switch (m)
{
case 2:
if (isLeap(year))
days = 29;
else
days = 28;
break;
case 4:
case 6:
case 9:
case 11:
days = 30;
break;
default:
days = 31;
break;
}
return days;
}
int DateDiff(Date date1, Date date2)
{
int days = 0;
// 循环后年份相同
while (date1.year != date2.year)
{
if (date1.year < date2.year)
{
days += year_days(date1.year);
date1.year++;
}
else
{
days -= year_days(date2.year);
date2.year++;
}
}
// 循环后月份相同
while (date1.month != date2.month)
{
if (date1.month < date2.month)
{
days += month_days(date1.year, date1.month);
date1.month++;
}
else
{
days -= month_days(date2.year, date2.month);
date2.month++;
}
}
days += (date2.day - date1.day);
return days;
}
vector<string> month_vec = {
"JAN", "FEB", "MAR", "APR",
"MAY", "JUN", "JUL", "AUG",
"SEP", "OCT", "NOV", "DEC"};
int main()
{
int year, mon, day;
char mon_s[4];
scanf("%d%3s%d", &day, mon_s, &year);
mon = find(month_vec.begin(), month_vec.end(), mon_s) - month_vec.begin() + 1;
if (dateCmp({year, mon, day}, DATE{1582, 10, 4}) <= 0)
{
cout << DateDiff({1, 1, 1}, {year, mon, day});
}
else
{
cout << DateDiff({1, 1, 1}, {year, mon, day}) - 10;
}
return 0;
}

京公网安备 11010502036488号