日期差值(上海交通大学复试上机题)心得
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int months[2][13] = { {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
bool IsLeapYear(int year) {
return (year % 400 == 0) || (year % 100 != 0 && year % 4 == 0);
}
int NumberOfYear(int year) {
if (IsLeapYear(year)) {
return 366;
} else {
return 365;
}
}
int main() {
int m, n;
int sum = 0;//统计差值
while (~scanf("%d%d", &m, &n)) {
//从年开始算起,m要大于n。
if (m / 10000 < n / 10000) {
swap(m, n);
}
//以m大于n的年份算月份,如果m月份小于n,从n月份
int submonth = m % 10000 / 100 - n % 10000 / 100;
int subyear = m / 10000 - n / 10000;
int row;
//从月开始算。
if (subyear == 0) {
row = IsLeapYear(m / 10000);
for (int j = n % 10000 / 100 + 1; j < m % 10000 / 100; ++j) {
sum += months[row][j];
}
} else if (subyear >= 1) {
for (int i = n / 10000 + 1; i < m / 10000; ++i) {
sum += NumberOfYear(i);
}
row = IsLeapYear(n / 10000);
for (int j = n % 10000 / 100 + 1; j <= 12; ++j) {
sum += months[row][j];
}
row = IsLeapYear(m / 10000);
for (int k = 1; k < m % 10000 / 100; ++k) {
sum += months[row][k];
}
}
//年月搞定了,开始搞月内日子
int mday = m % 100;
row = IsLeapYear(n / 10000);
int nday = months[row][n % 10000 / 100] - n % 100;
if (subyear == 0 && submonth == 0) {
sum = abs(mday - n % 100) + 1;
} else {
sum += mday + nday + 1;
}
printf("%d\n", sum);
}
return 0;
}
描述
有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们之间的天数为两天
输入描述:
有多组数据,每组数据有两行,分别表示两个日期,形式为YYYYMMDD
输出描述:
每组数据输出一行,即日期差值
示例1
输入:
20110412
20110422
输出:
11
思路
- 对于月内,使用绝对值+1方法
- 对于年内,使用判断完闰月之后,小日子向后数,大日子向前数,中间月份日子直接加。
- 对于年间,先判断中间年份的闰年与否,加上中间年份日子数,再按照年内计算。变通在于小年直接数到月底,大年从一月开始数。
注意
- 对于日期来说,前两个函数是标配,看题目之前就可以写。
- abs绝对值函数不要忘,这样就不用比大小交换赋值了。
ps:当时在写完最后一个printf代码时,发现sum会变得不一样,调试之后发现只要是printf以前的都是好的,当时很崩溃。哭着哭着发现。。。。。我sum最后一个把月内日子加起来的式子,是直接赋值,而不是+=。。。。。大家不要犯这种低级错误。