这是《C++算法宝典》算法篇的第09节文章啦~
如果你之前没有太多C++基础,请点击👉专栏:C++语法入门,如果你C++语法基础已经炉火纯青,则可以进阶算法👉专栏:算法知识和数据结构👉专栏:数据结构啦
目录
❀前言
🧠普通闰年
🧠世纪闰年
前言
无论是中小学编程竞赛还是大学生编程竞赛,日期模拟都是经常会出现的题目。
日期模拟经常会出现以下题型:
- 得到某年某月的天数
- 判断给定日期的合法性
- 给定年份,求这一年第n天的日期
- 给定年月日,求经过n天后的日期
- 查找两个日期之间有多少个回文日期... ...
得到某年某月的天数
得到某年某月的天数问题经常会作为其他问题的模板来使用。
首先我们需要存储一年中所有月份相对应的天数
int day[] = {0,31,28,31,30,31,30,31,31,30,31,30,31}
其中day[1]表示一月份最多31天,2月份先赋值为28天,具体天数还需要检测年份是否是闰年,如果是闰年还需要+1天
闰年分为两种:
普通闰年
年份是4的倍数,但不是100的倍数,例如2004、2020年等
世纪闰年
是400的倍数,例如1900不是世纪闰年,2000是世纪闰年,即:
if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
是闰年;
else
不是;
得到某年某月的天数
当月份不是2月时,就返回指定当前月份初始天数
当月份是2月时,判断年份是否是闰年,当年份为闰年成立时,leap值为1,不成立时值为0,初始天数加上leap的值即为2月份天数
int days[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// 得到某年某月的天数
int check(int y, int m)
{
if(m != 2) return days[m];
else
{
//特判 2 月
int leap = (y % 4 == 0 && y % 100 != 0 || y % 400 == 0);
return days[m] + leap;
}
}
判断日期的合法性
一般这样的题型会先给你一个格式,看是否符合这个格式,比如要满足20230701这样的格式才是合法的。
首先你需要分离出年份,再分离出月份,最后分离出日。
再分别判断年月日是否符合题意
if(m<1||m>12) 则月份不符合
if(d<1||d>(指定月份的总天数)) 则日不符合
注:年份一般不需要检查,但也要视题意而定
训练:第n天的日期
给定一个年份y和一个整数d,问这一年的第d天是几月几日?注意闰年的2月有29天。满足下面条件之一的是闰年:
1、年份是4的整数倍,而且不是100的整数倍;
2、年份是400的整数倍。
【输入描述】输入的第一行包含一个整数y,表示年份,年份在1900到2015之间(包含1900和2015)。
输入的第二行包含一个整数d,d在1至365之间。
【输出描述】输出两行,每行一个整数,分别表示答案的月份和日期。
【样例输入1】
2015
80
【样例输出】
3
21
第n天的日期参考代码
#include <iostream>
using namespace std;
int day[13]={0,31,0,31,30,31,30,31,31,30,31,30,31};
bool check(int n) //判断闰年
{
if(n%400==0||(n%4==0&&n%100!=0)) return true;
return false;
}
int main()
{
int m,n;
cin>>m>>n;
if(check(m)) day[2]=29;
else day[2]=28;
for(int j=1;j<=12;j++)
{
n-=day[j];
if(n<0){
cout<<j<<endl<<day[j]+n;
break;
}
if(n==0)
{
cout<<j<<endl<<day[j];
break;
}
}
return 0;
}
训练:日期距离
输入一个的日期,输出它和2014年5月17日相差有多少天?注意闰年的2月有29天。满足下面条件之一的是闰年:
1、年份是4的整数倍,而且不是100的整数倍;
2、年份是400的整数倍。
【输入描述】输入的第一行包含一个整数y,表示年份,年份在1到2014之间(包含1和2014)。
输入的第二行包含一个整数m,表示月份,m在1至12之间。
输入的第三行包含一个正整数d,表示日期,d在1至31之间。
【输出描述】输出两个日期之间相差的天数。
【输入样例】
1988
7
3
【输出样例】
9449
日期距离参考代码
#include <iostream>
using namespace std;
int day[13]={0,31,0,31,30,31,30,31,31,30,31,30,31};
bool check(int k) //判断闰年
{
if(k%400==0||(k%4==0&&k%100!=0))
return true;
return false;
}
int sum;//计算总天数
int main()
{
int m,n,d;
cin>>m>>n>>d;
if(check(m)) day[2]=29;
else day[2]=28;
for(int i=m+1;i<2014;i++) //计算完整的年份天数
{
if(check(i)) sum+=366;
else sum+=365;
}
if(m==2014)
{
for(int i=n+1;i<5;i++) //计算完整的月份的天数
sum+=day[i];
if(n==5) sum+=17-d;
else sum+=day[n]-d+17;
}
else
{
sum+=137; //2014.1.1~2014.5.17总天数
for(int i=n+1;i<=12;i++) //算上完整月份天数
sum+=day[i];
sum+=day[n]-d;
}
cout<<sum<<endl;
return 0;
}