算法09 日期相关模拟算法【C++实现】

这是《C++算法宝典》算法篇的第09节文章啦~

如果你之前没有太多C++基础,请点击👉专栏:C++语法入门,如果你C++语法基础已经炉火纯青,则可以进阶算法👉专栏:算法知识和数据结构👉专栏:数据结构

目录

前言

📕得到某年某月的天数

🧠普通闰年

🧠世纪闰年

📕得到某年某月的天数

📕判断日期的合法性

📕训练:第n天的日期

🧠第n天的日期参考代码

📕训练:日期距离

🧠日期距离参考代码


前言

无论是中小学编程竞赛还是大学生编程竞赛,日期模拟都是经常会出现的题目。

日期模拟经常会出现以下题型:

  • 得到某年某月的天数
  • 判断给定日期的合法性
  • 给定年份,求这一年第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;
}

从入门到算法,再到数据结构,查看全部文章请点击此处​​​​​icon-default.png?t=N7T8http://www.bigbigli.com/

  • 44
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bigbigli_大李

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值