日期相关的题目

题目:HJ73 计算日期到天数转换

描述

根据输入的日期,计算是这一年的第几天。

保证年份为4位数且日期合法。

进阶:时间复杂度:𝑂(𝑛) O(n) ,空间复杂度:𝑂(1) O(1) 

输入描述:

输入一行,每行空格分割,分别是年,月,日

输出描述:

输出是这一年的第几天

示例1

输入:

2012 12 31

输出:

366

复制

示例2

输入:

1982 3 4

输出:

63

思路:

首先拿到这个题目,我考虑的是输入的年份是否是闰年,因为闰年可能会导致出现天数的差异。

因此我们需要写一个判断是否是闰年的函数。(四年一闰,百年不闰,四百年一闰。)

if((year%4==0&&year%100!=0)||year%400==0)

我们写出判断闰年的函数之后,根据题干,还需要判断这个是月是在今年的第几个月,把在这之前的月份的天数进行相加。

由此,我们可以写一个数组用来存放月份之间相加的天数,例如4月21日,我们可以利用这个数组能够快速算出前三个月的总天数,只需要再加上第四个月的21天即可。

int monthdayarry[13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
int n = monthdayarry[month - 1] + day;

接下来只需要把闰年的判断和计算天数结合到一起就可以。 

完整提交结果:

#include <iostream>
using namespace std;

int main() {
    int day;
    int month;
    int year;
    cin >> year >> month >> day;
    //这里是进行计算每个月累加的结果,1月加2月天数为31+28=59,1月加2月加3月为59+31=90,依次类推
    int monthdayarry[13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
    //定义一个n,用来统计前面几个月的天数,再加上当月的天数即为它是今年的第几天
    int n = monthdayarry[month - 1] + day;
    //因为如果是闰年的话,需要考虑2月天数要加1,下面进行判断
    if (month > 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))){
         n += 1;
    }
    cout << n << endl;
    return 0;

}

题目:KY111 日期差值

描述

有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们之间的天数为两天

输入描述:

有多组数据,每组数据有两行,分别表示两个日期,形式为YYYYMMDD

输出描述:

每组数据输出一行,即日期差值

示例1

输入:

20110412
20110422

输出:

11

思路:

首先看到输入,我们需要把年月日进行提取,分离出来年、月、日,方便我们后续进行判断和操作。

对于年来说,我们只需要将输入除10000之后保留下结果的整数部分即可。

 对于日来说,我们只需要将输入除100之后,获得结果的小数部分即可。

对于月来说,我们需要将输入除10000之后,获取到小数部分之后,再除100,保留整数部分。

 这个部分我们可以写为一个函数:

void extractDateComponents(int date, int& year, int& month, int& day) {
    year = date / 10000;
    month = (date % 10000) / 100;
    day = date % 100;
}

接下来我们需要解决如何计算差值的问题,这个题目跟HJ73 计算日期到天数转换的思路差不多,我的想法是分别对两个日期进行计算,计算两个日期分别是那一年的第多少天,计算好总的日期之后进行相减。逻辑跟上面那个题差不多。

int dateToDayOfYear(int year, int month, int day) {
    int monthDayArray[13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
    int dayOfYear = monthDayArray[month - 1] + day;
    // 如果是闰年且月份大于2月,则多加一天
    if (month > 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))) {
        dayOfYear += 1;
    }
    return dayOfYear;
}

 但是仅仅是靠上面的逻辑判断是不够的,例如,20250211与20230211这个输出,来说我们就无法解决了,因此在上面的基础上我们进行改进。

既然我们上面的只能针对同一年,我们可以把基准调整为公元0年,20250211为公元0年的第多少天,20230211为公元0年的第多少天,二者再进行相减。但是需要考虑从公元0年到所在日期中有多少个闰年。

最后,题干要求:如果两个日期是连续的我们规定他们之间的天数为两天。因此,我们需要再最后的差值再加1。例如20230211与20230212. 相减之后值为1,但是11与12是连续的,因此需要加1.

完整提交结果:

#include <iostream>
#include <cmath>
using namespace std;

// 将日期转换为一年中的第几天
int dateToDayOfYear(int year, int month, int day) {
    int monthDayArray[13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
    int dayOfYear = monthDayArray[month - 1] + day;
    // 如果是闰年且月份大于2月,则多加一天
    if (month > 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))) {
        dayOfYear += 1;
    }
    return dayOfYear;
}

// 从日期中提取出年份、月份和日期
void extractDateComponents(int date, int& year, int& month, int& day) {
    year = date / 10000;
    month = (date % 10000) / 100;
    day = date % 100;
}

int main() {
    int date1, date2;
    // 持续读取输入的日期
    while (cin >> date1 >> date2) {
        int year1, month1, day1;
        int year2, month2, day2;

        // 提取第一个日期的年份、月份和日期
        extractDateComponents(date1, year1, month1, day1);
        // 提取第二个日期的年份、月份和日期
        extractDateComponents(date2, year2, month2, day2);

        // 计算第一个日期是这一年的第几天
        int dayOfYear1 = dateToDayOfYear(year1, month1, day1);
        // 计算第二个日期是这一年的第几天
        int dayOfYear2 = dateToDayOfYear(year2, month2, day2);

        // 如果两个日期在同一年
        if (year1 == year2) {
            cout << abs(dayOfYear1 - dayOfYear2) + 1 << endl;
        } else {
            // 计算不同年份的总天数
            //year1*365表示从公元0年到year1年的天数
            //dayOfyear1表示今天是今年的多少天
            //year1 / 4 - year1 / 100 + year1 /400 表示需要计算0到year1之间的闰年个数,如果是闰年多加1天
            //四年一闰,百年不闰,四百年一闰
            int totalDays1 = (year1 * 365) + dayOfYear1 + (year1 / 4 - year1 / 100 + year1 /400);
            int totalDays2 = (year2 * 365) + dayOfYear2 + (year2 / 4 - year2 / 100 + year2 /400);
            cout << abs(totalDays1 - totalDays2) + 1 << endl;
        }
    }
    return 0;
}


  • 14
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值