例2.3 日期差值 - 九度教程第6题(日期类问题)

例2.3 日期差值(九度教程第6题)

题目

时间限制:1 秒 内存限制:32 兆 特殊判题:否
题目描述:
有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们之间的天数为两天
输入:
有多组数据,每组数据有两行,分别表示两个日期,形式为YYYYMMDD
输出:
每组数据输出一行,即日期差值
样例输入:
20110412
20110422
样例输出:
11
来源:
2009年上海交通大学计算机研究生机试真题

解析:

该例题考察了日期类问题最基本的问题求两个日期间的天数差

解决这类区间问题有一个统一的思想:把原区间问题统一到起点确定的区间问题上去。这样做有一个巨大的好处:预处理,可以在程序真正开始处理输入数据之前,预处理出所有日期与原点日期的天数差并保存起来。

所以统一设一个原点时间:如0000年1月1日。当要求两个特定日期的天数差时,只要将它们与原点日期的天数差相减,便能得到这两个特定日期之间的天数差(必要时加绝对值)。

还需注意:闰年。

注:

1,定义了一个类,可以用来表示日期,还可以自动计算出下一个日期。

2,为了判断该年是否为闰年,定义了一个

3,保存某特定日期与原点日期的天数差时,使用了三维数组,用年、月、日分别表示该数组下标。这将日期本身与其存储地址联系了起来,只需直接利用它的年月日数字即可找到保存的值。(将数据本身与数据存储地址联系起来,这是Hash的思想,也是Hash的一种基本方式。)

4,输入采用了某种技巧。使用%4d来读取该八位数的前四位并赋值给代表年的变量。  利用在%d之间插入数字读取特定位数的数字的技巧,值得去采用。

5,将buf[5001][13][32]这个相对比较耗费内存的数组定义为全局变量,是有原因的。  由于需要耗费大量内存,若在main函数中定义该数组,该函数所使用的栈空间不足以提供如此庞大的内存,出现栈溢出,导致程序异常终止。

因此,今后凡是涉及此类需要开辟大量内存空间的情况,必须在函数main体外定意,即定义为全局变量。或者在函数中使用malloc等函数动态申请变量空间。

大致思路:

        自定义结构体Date、自定义一个时间原点(0年1月1日)、预存每月的天数(二月作特殊处理),预处理出所有日期与原点日期的天数差,保存在一个三维数组buf[][][]中。

        输入要计算的两个日期,求对应两个buf[][][]值的绝对值即可。

代码: 

#include<stdio.h>

//定义宏判断是否为闰年,方便计算每月天数
#define IsYeap(x) x%4==0 && x%100!=0 || x%400==0 ?1:0

int dayOfMonth[13][2]={
        0,0,
        31,31,
        28,29,
        31,31,
        30,30,
        31,31,
        30,30,
        31,31,
        31,31,
        30,30,
        31,31,
        30,30,
        31,31
};//预存每月的天数,注意二月作特殊处理

struct Date{  //日期类,方便日期的推移
    int day;
    int month;
    int year;
    void nextDay(){//计算下一天的日期
        day++;
        if(day>dayOfMonth[month][IsYeap(year)])//若日数超过了当月最大天数
        {
            day=1;
            month++; //进入下一月
            if(month>12){
                month=1;
                year++;//进入下一年
            }
        }
    }
};

int buf[5001][13][32];//保存预处理的天数
int Abs(int x){           //求绝对值
    return x<0?-x:x;
}

int main()
{
    Date tmp;
    int cnt=0; //天数计数
    tmp.day=1;
    tmp.month=1;
    tmp.year=0; //初始化日期类对象为0年1月1日

    while(tmp.year!=5001){//日期不超过5000年
        buf[tmp.year][tmp.month][tmp.day]=cnt;  //将该日与0年1月1日的天数差保存起来
        tmp.nextDay();  //计算下一天日期
        cnt++;          //计数器累加代表与原点日期的间隔又增加一天
    }

    int d1,m1,y1;
    int d2,m2,y2;
    while(scanf("%4d%2d%2d",&y1,&m1,&d1)!=EOF){
        scanf("%4d%2d%2d",&y2,&m2,&d2);//读入要计算的两个日期
        printf("%d\n",Abs(buf[y1][m1][d1]-buf[y2][m2][d2])+1);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_39450145

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值