儒略历
儒略历
题目描述
在 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; }