日期问题难度并不大,但是代码量非常大,需要较高的熟练度,因此需要着重练习,主要涉及数组和循环两个方面的知识点,需要熟练的测试代码。
两个经典题型
闰年
闰年满足以下两个条件的任意一个
- 能够被400整除
- 不能够被100整除,并且能够被4整除
year%400||year%100&&year%4
给定月份判断天数
定义一个数组month[13]={0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},可以通过空间换时间,只要将月份作为数组序号,返回数组值即可。
题目:某年的第几日
解题思路
方案一(代码简洁,不通用)
- 先算到该月的头一天是该年的第几天
- 再算今天是该月的第几天
- 上述两个值加起来即为今年的第几天
代码
#include <cstdio>
int main() {
int year, month, day;
int month_Day[13]={0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int total_day[13]={0};
for (int mon = 2; mon < 13; ++mon) {
//到mon月1日的天数 = 到mon-1月1日的天数+第mon-1月的天数
total_day[mon] = total_day[mon-1] + month_Day[mon-1];
}
while(scanf("%d%d%d", &year, &month, &day) != EOF){
//如果是闰年
bool isLeap = year%400==0||year%100!=0&&year%4==0;
if (isLeap== true&& month>=3){
printf("%d\n",total_day[month]+day+1);
} else{
printf("%d\n",total_day[month]+day);
}
}
return 0;
}
方案二(通用解决方案:next day)
一天天往后迭代,直到算到所要的日期
示例:
输入:
2000 3
2000 31
2000 40
2000 60
2000 61
2001 60
输出:
2000-01-03
2000-01-31
2000-02-09
2000-02-29
2000-03-01
2001-03-01
#include <cstdio>
int main() {
int year, n;
int month_Day[13]={0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
while(scanf("%d%d",&year,&n)!=EOF){
int mon = 1;
int day = 1;
for (int i = 0; i < n-1; ++i) {
bool isLeap = year%400==0||year%100!=0&&year%4==0;
if (isLeap){
month_Day[2]=29;
} else{
month_Day[2]=28;
}
++day;
if (day > month_Day[mon]){//日子超过了当月的天数
++mon;
day=1;
if (mon>12){//过年了
mon = 1;
++year;
}
}
}
printf("%04d-%02d-%02d\n",year,mon,day);
}
return 0;
}
%4d与%04d的区别:
- %4d:至少4位10进制数,不足用空格补
- %04d:至少4位10进制数,不足用0补