【Codeup1928 】日期差值
题目地址
http://codeup.cn/problem.php?cid=100000578&pid=0
题目描述
有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们之间的天数为两天。
输入
有多组数据,每组数据有两行,分别表示两个日期,形式为YYYYMMDD。
输出
每组数据输出一行,即日期差值。
样例输入
20130101
20130105
样例输出
5
AC代码
#include<cstdio>
int month[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
bool isLeap(int year);
int main() {
int time1, y1, m1, d1;
int time2, y2, m2, d2;
while (scanf("%d%d", &time1, &time2) != EOF) {
if (time2 > time1) {
int temp = time1;
time1 = time2;
time2 = temp;
}
d1 = time1 % 100;
d2 = time2 % 100;
m1 = time1 / 100 % 100;
m2 = time2 / 100 % 100;
y1 = time1 / 10000;
y2 = time2 / 10000;
int num = 1; //记录结果
while (y1 > y2 || m1 > m2 || d1 > d2)
{
if (isLeap(y2)) month[2] = 29;
else month[2] = 28;
d2++;
if (d2 == month[m2] + 1){
m2++;
d2 = 1;
}
if (m2 == 13) {
y2++;
m2 = 1;
}
num++;
}
printf("%d\n", num); //输出
}
return 0;
}
bool isLeap(int year) {//判断是否是闰年
return ((year % 4 == 0) &&( year % 100 != 0)) || (year % 400 == 0);
}
解题过程
基本思路
首先要注意有多组数据,使用while…EOF读到文件尾。需要比较两个数据的大小进行交换,保证第一个日期是最大的。通过给第二个日期加天数的方式使二者相等,得到相差的天数。
对数据进行取余整除等获取年月日,也可以使用字符串读取然后用sscanf进行转换获取年月日。
采用一维数组记录每个月的天数用于判断,通过空间换取时间,当为闰年的时候需要对二月的天数进行修改,也可以采用二维数组进行记录。
错误代码
解题过程中算法没有错,单组测试也没有问题,提交到平台一直是答案错误50。也就是说通过了部分用例。
错误代码如下:
#include<cstdio>
int month[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
bool isLeap(int year);
int main() {
int time1, y1, m1, d1;
int time2, y2, m2, d2;
int num = 1;
while (scanf("%d%d", &time1, &time2) != EOF) {
if (time2 > time1) {
int temp = time1;
time1 = time2;
time2 = temp;
}
d1 = time1 % 100;
d2 = time2 % 100;
m1 = time1 / 100 % 100;
m2 = time2 / 100 % 100;
y1 = time1 / 10000;
y2 = time2 / 10000;
while (y1 > y2 || m1 > m2 || d1 > d2)
{
if (isLeap(y2)) month[2] = 29;
else month[2] = 28;
d2++;
if (d2 == month[m2] + 1){
m2++;
d2 = 1;
}
if (m2 == 13) {
y2++;
m2 = 1;
}
num++;
}
printf("%d\n", num);
}
return 0;
}
bool isLeap(int year) {//判断是否是闰年
return ((year % 4 == 0) &&( year % 100 != 0)) || (year % 400 == 0);
}
错误原因是记录天数的num声明并初始化在循环体外,当计算第二组数据是,num保留了前一组的结果并累加导致错误,可在每次循环中重新给num赋值解决问题,或者直接声明在循环体类。这个错误导致自己单组数据测试看不出来问题,也是一个教训。
优化
可以通过直接判断第二个日期的下一年是否为闰年对天数进行加366或365,同时年数加一,将第二个的日期调整到第一个日期的前一年,再进行一天天的累加。具体改写如下:
while (y1 > y2 || m1 > m2 || d1 > d2)
{
if (y1 - 1 > y2) {
y2++;
if (isLeap(y2)) num += 366;
else num += 365;
continue;
}
if (isLeap(y2))
month[2] = 29;
else
month[2] = 28;
d2++;
if (d2 == month[m2] + 1)
{
m2++;
d2 = 1;
}
if (m2 == 13) {
y2++;
m2 = 1;
}
num++;
}
大大加快了速度,缩短至4ms,对比结果如图:
有很多种解法可以考虑,列如通过定义结构体等,但最终执行结果耗费了大量内存,时间效率上也没有太大改善。