日期差值(acwing每日一题)

题目描述:

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

输入格式:

输入包含多组测试数据。

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

输出格式:

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

数据范围:

年份范围 [1,9999]
保证输入日期合法。
测试数据的组数不超过 100。

输入样例:

20110412
20110422

输出样例:

11

分析步骤:

  第一:大家遇到日期问题的时候可以先把日期类的模板写上去,例如:is_leap(这是判断是否是闰年);get_month_days(这是计算每个月份的日子);get_total(这是计算总共的日期数)。写完这一个模板大家就会对这个问题,有个更加清晰的认识,就容易ac。

  第二:对于这道题目,他是没有一个结束标识的,所以我们要在while的循环条件中去判断是否到了文件末尾(EOF == end of file),并且输入时运用scanf的格式可以为我们省一些代码。这样我们的y1,m1,t1求出的就是日月年

int main()
{
    int y1 , m1 , t1;
    int y2 , m2 , t2;
    while(scanf("%04d%02d%04d",&y1,&m1,&t1) != EOF){
        scanf("%04d%02d%04d",&y2,&m2,&t2);
        cout<<abs(get_total(y1,m1,t1) - get_total(y2,m2,t2))+1<<endl;   
    }
    return 0;
}

  第三:我们去计算总的天数,所以就编写一个get_total的函数,计算从第一年到给定年的天数,因为一年至少365天,如果是闰年才要+1,所以只需每一年都判断一下是否为闰年即可;其次我们计算月份天数,从第一月到给定的月份,让res去加上因为每个月份的天数是不一样的,所以我们在单独写个get_month_days的函数去计算给定年份的从一月到给定的月份有多少天;最终加上天数就得出了我们的res答案。

int get_total(int year , int month , int day){
    int res = 0;
    for(int i =1 ; i < year ; i++){
        res +=365 + is_leap(i);
    }
    
    for(int i = 1; i < month ; i++){
       res += get_month_days(year , i);    
    }
    res += day;
    return res;
    
}

  第四:从第三步可以知道,我们还需要写一个计算月份天数的函数,所以这一步就是完善这个函数。我们设定个res。注意!!!!这个res只在get_month_days这个函数里有用,total里的res是不一样的,两者不一样,不是同一个,因为这些res都只是区间定义只能在特定的区间才可以起作用。接下来,把每一月的天数都加起来,如果月份是2月的话,我们就判断当年是不是闰年如果是就+1.最后返回res。

int get_month_days(int y , int m){
    int res = 0;
    res += months[m] ;
    if(m==2) res += is_leap(y);
    return res;
}

  第五:两个日期的结果减去之后,在计算的绝对值(因为没说两个数据一定谁前谁后)+1就可以得出答案了。

代码:

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

int months[]={0,31,28,31,30,31,30,31,31,30,31,30,31};

int is_leap(int y){
    if(y % 400 == 0 || (y % 4 == 0 and y % 100 != 0)) return 1;
    return 0;
}

int get_month_days(int y , int m){
    int res = 0;
    res += months[m] ;
    if(m==2) res += is_leap(y);
    return res;
}

int get_total(int year , int month , int day){
    int res = 0;
    for(int i =1 ; i < year ; i++){
        res +=365 + is_leap(i);
    }
    
    for(int i = 1; i < month ; i++){
       res += get_month_days(year , i);    
    }
    res += day;
    return res;
    
}

int main()
{
    int y1 , m1 , t1;
    int y2 , m2 , t2;
    while(scanf("%04d%02d%04d",&y1,&m1,&t1) != EOF){
        scanf("%04d%02d%04d",&y2,&m2,&t2);
        cout<<abs(get_total(y1,m1,t1) - get_total(y2,m2,t2))+1<<endl;
        
    }
    
    
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值