二 日期类问题
此类问题解题思路: 定一个锚点日期,如0年1月1日,先算出往后多少年内每一日子距离这个锚点的天数,例如要算两个日期间天数时,便可以将两个日期距离锚点日期之间的天数相减,即可得到。
题目描述:
有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们之间的天数为两天
输入:
有多组数据,每组数据有两行,分别表示两个日期,形式为YYYYMMDD
输出格式:
每组数据输出一行,即日期差值。
样例输入:
20180428
20181213
样例输出:
230
来源:
2009年上海交通大学计算机研究生机试真题
#include<bits/stdc++.h>
#define ISYEAP(x) x%100!=0 && x%4==0 || x%400==0 ? 1:0
//定义宏判断是否是闰年,方便计算每月天数
using namespace std;
int Day[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 d; // day
int m; // mouth
int y; // year
void next_Day(){//计算下一天的日期
d++;
if(d>Day[m][ISYEAP(y)]){//若日数超过了当月最大日数
d = 1;
m++;//进入下一月
if(m>12){//月数超过12
m = 1;
y++;//进入下一年
}
}
}
};
int buf[5001][13][32]; //保存预处理的天数
int abs(int x){//求绝对值
return x < 0 ? -x:x;
}
int main()
{
Date tmp;
int cnt = 0;//天数计数
tmp.d = 1;
tmp.m = 1;
tmp.y = 0;//初始化日期类对象为0年1月1日
while(tmp.y < 5001){//日期不超过5000年
buf[tmp.y][tmp.m][tmp.d] = cnt;//将该日与0年1月1日的天数差保存起来
tmp.next_Day();//计算下一天日期
cnt++;//计数器累加,每经过一天计数器即+1,代表与原点日期的间隔又增加一天
}
int d1, m1, y1;
int d2, m2, y2;
while(scanf("%4d%2d%2d", &y1, &m1, &d1) != EOF){
scanf("%4d%2d%2d", &y2, &m2, &d2);//读入要计算的两个日期
cout << abs(buf[y2][m2][d2]-buf[y1][m1][d1])+1 << endl;//用预处理的数据计算两日期差值,注意需对其求绝对值
}
return 0;
}
扩展:
假如问题需要我们输出某个特定的日期,是那年的第几天,只需要用该日期距离锚点日期的天数 — 那年元旦距离锚点日期的天数,即可。