Codeup 1928

【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,对比结果如图:
在这里插入图片描述
有很多种解法可以考虑,列如通过定义结构体等,但最终执行结果耗费了大量内存,时间效率上也没有太大改善。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值