题目:HJ73 计算日期到天数转换
描述
根据输入的日期,计算是这一年的第几天。
保证年份为4位数且日期合法。
进阶:时间复杂度:𝑂(𝑛) O(n) ,空间复杂度:𝑂(1) O(1)
输入描述:
输入一行,每行空格分割,分别是年,月,日
输出描述:
输出是这一年的第几天
示例1
输入:
2012 12 31
输出:
366
复制
示例2
输入:
1982 3 4
输出:
63
思路:
首先拿到这个题目,我考虑的是输入的年份是否是闰年,因为闰年可能会导致出现天数的差异。
因此我们需要写一个判断是否是闰年的函数。(四年一闰,百年不闰,四百年一闰。)
if((year%4==0&&year%100!=0)||year%400==0)
我们写出判断闰年的函数之后,根据题干,还需要判断这个是月是在今年的第几个月,把在这之前的月份的天数进行相加。
由此,我们可以写一个数组用来存放月份之间相加的天数,例如4月21日,我们可以利用这个数组能够快速算出前三个月的总天数,只需要再加上第四个月的21天即可。
int monthdayarry[13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
int n = monthdayarry[month - 1] + day;
接下来只需要把闰年的判断和计算天数结合到一起就可以。
完整提交结果:
#include <iostream>
using namespace std;
int main() {
int day;
int month;
int year;
cin >> year >> month >> day;
//这里是进行计算每个月累加的结果,1月加2月天数为31+28=59,1月加2月加3月为59+31=90,依次类推
int monthdayarry[13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
//定义一个n,用来统计前面几个月的天数,再加上当月的天数即为它是今年的第几天
int n = monthdayarry[month - 1] + day;
//因为如果是闰年的话,需要考虑2月天数要加1,下面进行判断
if (month > 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))){
n += 1;
}
cout << n << endl;
return 0;
}
题目:KY111 日期差值
描述
有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们之间的天数为两天
输入描述:
有多组数据,每组数据有两行,分别表示两个日期,形式为YYYYMMDD
输出描述:
每组数据输出一行,即日期差值
示例1
输入:
20110412 20110422
输出:
11
思路:
首先看到输入,我们需要把年月日进行提取,分离出来年、月、日,方便我们后续进行判断和操作。
对于年来说,我们只需要将输入除10000之后保留下结果的整数部分即可。
对于日来说,我们只需要将输入除100之后,获得结果的小数部分即可。
对于月来说,我们需要将输入除10000之后,获取到小数部分之后,再除100,保留整数部分。
这个部分我们可以写为一个函数:
void extractDateComponents(int date, int& year, int& month, int& day) {
year = date / 10000;
month = (date % 10000) / 100;
day = date % 100;
}
接下来我们需要解决如何计算差值的问题,这个题目跟HJ73 计算日期到天数转换的思路差不多,我的想法是分别对两个日期进行计算,计算两个日期分别是那一年的第多少天,计算好总的日期之后进行相减。逻辑跟上面那个题差不多。
int dateToDayOfYear(int year, int month, int day) {
int monthDayArray[13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
int dayOfYear = monthDayArray[month - 1] + day;
// 如果是闰年且月份大于2月,则多加一天
if (month > 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))) {
dayOfYear += 1;
}
return dayOfYear;
}
但是仅仅是靠上面的逻辑判断是不够的,例如,20250211与20230211这个输出,来说我们就无法解决了,因此在上面的基础上我们进行改进。
既然我们上面的只能针对同一年,我们可以把基准调整为公元0年,20250211为公元0年的第多少天,20230211为公元0年的第多少天,二者再进行相减。但是需要考虑从公元0年到所在日期中有多少个闰年。
最后,题干要求:如果两个日期是连续的我们规定他们之间的天数为两天。因此,我们需要再最后的差值再加1。例如20230211与20230212. 相减之后值为1,但是11与12是连续的,因此需要加1.
完整提交结果:
#include <iostream>
#include <cmath>
using namespace std;
// 将日期转换为一年中的第几天
int dateToDayOfYear(int year, int month, int day) {
int monthDayArray[13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
int dayOfYear = monthDayArray[month - 1] + day;
// 如果是闰年且月份大于2月,则多加一天
if (month > 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))) {
dayOfYear += 1;
}
return dayOfYear;
}
// 从日期中提取出年份、月份和日期
void extractDateComponents(int date, int& year, int& month, int& day) {
year = date / 10000;
month = (date % 10000) / 100;
day = date % 100;
}
int main() {
int date1, date2;
// 持续读取输入的日期
while (cin >> date1 >> date2) {
int year1, month1, day1;
int year2, month2, day2;
// 提取第一个日期的年份、月份和日期
extractDateComponents(date1, year1, month1, day1);
// 提取第二个日期的年份、月份和日期
extractDateComponents(date2, year2, month2, day2);
// 计算第一个日期是这一年的第几天
int dayOfYear1 = dateToDayOfYear(year1, month1, day1);
// 计算第二个日期是这一年的第几天
int dayOfYear2 = dateToDayOfYear(year2, month2, day2);
// 如果两个日期在同一年
if (year1 == year2) {
cout << abs(dayOfYear1 - dayOfYear2) + 1 << endl;
} else {
// 计算不同年份的总天数
//year1*365表示从公元0年到year1年的天数
//dayOfyear1表示今天是今年的多少天
//year1 / 4 - year1 / 100 + year1 /400 表示需要计算0到year1之间的闰年个数,如果是闰年多加1天
//四年一闰,百年不闰,四百年一闰
int totalDays1 = (year1 * 365) + dayOfYear1 + (year1 / 4 - year1 / 100 + year1 /400);
int totalDays2 = (year2 * 365) + dayOfYear2 + (year2 / 4 - year2 / 100 + year2 /400);
cout << abs(totalDays1 - totalDays2) + 1 << endl;
}
}
return 0;
}