日期问题难度并不大,但是代码量非常大,需要较高的熟练度,因此需要着重练习,主要涉及数组和循环两个方面的知识点,需要熟练的测试代码。
两个经典题型
闰年
闰年满足以下两个条件的任意一个
- 能够被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补