日期类问题:
1.基本问题:
求两个日期间的天数差,即求以两个特定日期为界的日期区间的长度。
2.套路:
将原区间问题统一到起点确定的区间问题上去(比如与0000年1月1日的日期之差)。这样处理可以对数据进行预处理,在输入之前就预处理出所有日期与原点日期之间的天数差保存起来,当数据真正开始输入时,只需O(1)的时间复杂度将保存的数据读出即可,是一种空间换时间的重要手段。
3.注意的要点——闰年:
每逢闰年2月将会有29天。闰年的判定——当年数不能被100整除时若其能被4整除则为闰年,或者其能被400整除也是闰年。即Year0!=0&&Year%4==0||Year@0==0。
例2.3 日期差值
AC代码:
#include<cstdio> using namespace std; bool LeapYear(int x) { return (x % 100 != 0 && x % 4 == 0) || x % 400 == 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][LeapYear(Year)]) { Day = 1; Month++; if (Month > 12) { Month = 1; Year++; } } } }; int days[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;//初始化对象为0000年1月1日 while (tmp.Year != 5001)//预处理 { days[tmp.Year][tmp.Month][tmp.Day] = cnt;//将该日与0000年1月1日的天数差保存起来 tmp.NextDay();//计算下一天的日期 cnt++;//计数器累加,每经过一天计数器加1,表示与原点日期间隔又增加一天 } int d1, m1, y1, d2, m2, y2; while (scanf("M--", &y1, &m1, &d1) != EOF) { scanf("M--", &y2, &m2, &d2); printf("%d\n", Abs(days[y2][m2][d2] - days[y1][m1][d1] + 1)); } return 0; } #include<cstdio> #include<cstring> #include<iostream> using namespace std; int month[13][2] = { 0, 0, 31,31,29,28,31,31,30,30,31,31,30,30,31,31,31,31,30,30,31,31,30,30,31,31 }; bool isLeapYear(int x) { return (x % 4 && !(x % 100)) || (x % 400); } int main() { int y1, m1, d1, y2, m2, d2; int cnt = 1; while (scanf("M--", &y1, &m1, &d1) != EOF && scanf("M--", &y2, &m2, &d2) != EOF) { while (y1 != y2 || m1 != m2 || d1 != d2) { d1++; cnt++; if (d1 > month[m1][isLeapYear(y1)]) { d1 = 1; m1++; if (m1 > 12) { m1 = 1; y1++; } } } printf("%d\n", cnt); } //system("pause"); return 0; } 二刷例2.4 Day of Week
AC代码:
#include<cstdio> #include<cstring> using namespace std; bool LeapYear(int x) { return (x % 100 != 0 && x % 4 == 0) || x % 400 == 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 }; char WeekName[7][20] = { "Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday" }; char MonthName[13][20] = { "", "January","February","March","April","May","June","July","August","September","October","November","December" }; struct Date { int Day; int Month; int Year; void NextDay()//计算下一天的日期 { Day++; if (Day > dayOfMonth[Month][LeapYear(Year)]) { Day = 1; Month++; if (Month > 12) { Month = 1; Year++; } } } }; int days[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;//初始化对象为0000年1月1日 while (tmp.Year != 5001)//预处理 { days[tmp.Year][tmp.Month][tmp.Day] = cnt;//将该日与0000年1月1日的天数差保存起来 tmp.NextDay();//计算下一天的日期 cnt++;//计数器累加,每经过一天计数器加1,表示与原点日期间隔又增加一天 } int d, m, y; char s[20]; while (scanf("%d%s%d", &d, s, &y) != EOF) { for (m = 1; m <= 12; m++) { if (strcmp(s, MonthName[m]) == 0)break; } int index = days[y][m][d] - days[2019][6][10];//比较对象为2019年6月10日,周一 printf("%s\n", WeekName[(index % 7 + 7) % 7]);//处理复数情况 } return 0; }
转载于:https://www.cnblogs.com/yun-an/p/11028183.html
相关资源:华为机考-软件测试试题.docx