两个日期的天数差,解决这类问题的统一思想是:把原区间问题统一到确定区间上去,如本问题中将特定问题统一到与一个原点时间(0000年01月01日)的天数差,将两个日期与原点的日期天数差相减。利用数据预处理的好处是:在程序开始输入所有数据之前,将所有日期与原点日期的天数差保存起来,当数据真正开始输入时,只需要O(1)的时间将数据取出。
另一个需要注意的问题是闰年的计算方法
扩展:若要计算特定日期是当年的第几天,只需将该日期与原点是日期的天数差减去当年元旦与原点日期的天数差可得。
#include<stdio.h> #define ISYEAP(x) x%100!=0 && x%4==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)//月数超过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) { buf[tmp.Year][tmp.Month][tmp.Day]=cnt;//将改日与0年1月1日的天数差保存起来 tmp.nextDay();//计算下一个日期 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); printf("%d\n",Abs(buf[y1][m1][d1]-buf[y2][m2][d2])+1); } return 0; }