题目描述:
有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们之间的天数为两天
输入:
有多组数据,每组数据有两行,分别表示两个日期,形式为YYYYMMDD
输出:
每组数据输出一行,即日期差值
做题思路:
样例输入:
20110412
20110422
样例输出:
11
对于日期类:年月日,就像学生信息一样,用结构体处理。
struct Date{
int year;
int month;
int day;
status fun();//待添加
}
这里提出一个新的概念:预处理
首先无论输入的两行数字是什么,我们不妨都初始化一个日期init_date:如0000年1月1日,分别计算输入的两个日期离init_date的日期差值,然后再将这两个差值相减,即得到结果。举个栗子。小A就是初始化Init_people,他的年龄是0岁0月,小B的年龄是7岁10个月,小C的年龄是15岁2个月,问小B与小C的月份之差。显然,计算直接计算其实有点点的绕(毕竟不是十进制,像我这种直白的人类处理起来就是容易搞错),如果先计算小B与小A的月份差:
7
∗
12
+
10
−
0
=
94
(
m
o
n
t
h
)
7*12+10-0 = 94(month)
7∗12+10−0=94(month) 小C与小A的月份差:
15
∗
12
+
2
−
0
=
182
(
m
o
n
t
h
)
15*12+2-0=182(month)
15∗12+2−0=182(month) 所以小B与小C月份差:
∣
94
−
182
∣
=
88
(
m
o
n
t
h
)
|94-182|=88(month)
∣94−182∣=88(month)
上面就是解决本题的一个大体思路,但显然本题还有很多的细节和难点:
- 闰年
- 每个月份的天数
首先对于闰年的判断,是每个人学习C语言入门必备的一个知识点:闰年是4的倍数但不能是100的倍数,或者是400的倍数。就是公元100年不是闰年,但公元4年,400年是闰年。
bool isLeap(int year)
{
if( (year%4 == 0&&year%100 != 0 )||year%400 == 0 )
return true;
else
return false;
}
其次,判断完闰年,我们可以开始处理每个月份的天数了,众所周知,只有2月摇摆不定,所以我们不妨建立一个二维数组:int daysOfMonth[13][2]
int daysOfMonth[13][2]={{0,0},
{31,31},
{28,29},//闰年是29天~
{31,31},
{30,30},
{31,31},
{30,30},
{31,31},
{31,31},
{30,30},
{31,31},
{30,30},
{31,31}
}
现在就可以开始进行预处理部分了:
假设此时我们简化问题:计算某一天的明天的日期。这里要考虑到天数是否超过了30(31,28,29),月数是否超过12?
void nextDay()
{
Day++;
if(Day>DaysOfMonth[Month][isLeap(Year}]//月份加1
{
Day-=DaysOfMonth[Month][isLeap(Year}];//Day = 1;
Month++;
}
if(Month>12)
{
Month-=12;//Month = 1;
Year++;
}
接下来我们定义一个三维数组:int date[year][month][days]
具体来说,先设定一个范围(输入的年份在0~5000年)则可定义为:int date[5001][13][32]
(不用下标零)
所谓预处理就是先填充这个数组,如某个数组单元date[y0][m0][d0]填充的内容就是y0年m0月d0日离初始0000年1月1日的GapDays.
gapDays = 0;//天数计时器
Date tmp;
tmp.year=0;
tmp.month = tmp.day = 1;
while(tmp.year!=5001)//日期不超过5001年
{
date[tmp.year][tmp.month][tmp.day]=gapDays;
tmp.nextDay();
gapDays++;//时间差
}
有了上述预处理的过程,我们就可以根据输入的时间从三维数组里直接找到(记起了学数据结构的时候,老师一直强调的数组具有随机存取的特性。)其对应的gapDays,然后两个相减就可以了。
结合上述分析,就可以写程序了。
//2_3日期差值
//针对此类问题,我们要量化每个月的天数
#include<stdio.h>
bool isLeap(int d)
{
if((d%4==0&&d%100!=100)||d%400==0)
return true;
else
return false;
}
int abs(int a)
{
return a>0?a:(-a);
}
int daysOfMonth[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 year;
int month;
int day;
void nextDay()
{
day++;
if(day>daysOfMonth[month][isLeap(year)])
{
day = 1;
month++;
if(month > 12)
{
month = 1;
year++;
}
}
}
};
int date[5001][13][32];
int main()
{
Date tmp;
tmp.year = 0;
tmp.month = 1;
tmp.day = 1;
int gapDays= 0;
while(tmp.year!=5001)
{
date[tmp.year][tmp.month][tmp.day]=gapDays;
tmp.nextDay();
gapDays++;
}
int y1,y2,
m1,m2,
d1,d2;
while(scanf("%4d%2d%2d",&y1,&m1,&d1)!=EOF)
{
scanf("%4d%2d%2d",&y2,&m2,&d2);
int ans;
ans = abs(date[y1][m1][d1]-date[y2][m2][d2]);
printf("%d\n",ans+1);//相邻两天记作两天
}
return 0;
}