儒略历

儒略历

题目描述

在 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;
}

全部评论

相关推荐

2024-12-21 10:42
已编辑
江西软件职业技术大学 Java
新宿站不停:该提升学历就提升学历,菜了就多练。没事找牛马公司虐自己是吧? 谁没事说自己“经验少”,这不自己把自己塞剎鼻hr嘴里找🐴吗
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务