先上题目不多BB(因为后面要说很多,嘿嘿) alt

altalt

很多长的有那么一些小帅的观众可能看见题目就说了:你这考虑前天是哪天直接减个二不就行了。(好家伙是直接绯红之王了属于是,但是当我们细细品味时会发现这题有很多的地方要特别当心。

普通的年月日大家都会算但是这题说的是给定2000到3000中任意一年的任意月份和任意某天,这其中就存在许多变数(简直就是女人心海底针(不是。

先缕一缕思路,年份里有二月,二月比较特殊只有当他是闰年的时候才有29天而平年则有28天。所以咱们要先判断这一年是否为闰年(这个闰年是不是像爱探险的朵拉里面的捣蛋鬼?手动滑稽),看完了年月咱们再来看看日,众所周知,每月月底都会有那么一批小伙伴吃土(手动滑稽X2),而每月初就会很潇洒。由此我们不难想到每月1.2号向前推两天是月底。

alt 有的小伙伴听到这里可能是这个表情,这么多情况我要怎么搞啊。

咱们要最想要的就是这题像葫芦娃救爷爷一般将答案一步步的送给咱们,所以咱们就可以开干了。

书接上文,上文中说先有普通的年月日那咱们可以怎么做啊?没错直接给他安排上

#include<stdio.h>
int main()
{
    int a,b,c;//a,b,c分别指的是年月日
    scanf("%d-%d-%d",&a,&b,&c);
    if(c>2)
    { c=c-2;}
    else{b=b-1;//注意啦,这里将除了上面的特殊情况都包含了哟。(月份,年份,日期的判断在下面
         if(b==0){
                   a=a-1;
                    b=12;}

在这里提一下特殊的月份那就是12月,一月往前推就有可能推到12月所以else后面就是判断这种情况的。

稍微解释一下

if上面的b=b-1当输入的b为1时变量b就被赋为1-1=0,而0即是前一年的12月份,所以这里可用一个if语句来解决这个问题即a=a-1(退回到前一年,月份为12),在这里有的同学已经忍不住要说了,那你这个日哦不具体哪一天怎么判断啊,这个咱先不急,先将月份的问题给解决再慢慢来solve it.

------------------------分割线-------------------------------------------------------

alt

一般情况讨论过了之后咱们就要开始对二月进行一次从头到脚的全面检查。二月特殊的原因上面讲过了是因为闰年的存在。闰年判断的标准是什么大家应该都了解,但还是有人不太熟悉,俺这里放一下代码哦

```(a%400==0)||(a%100!=0&&a%4==0)

做个简单的说明,条件一是年份除以400余为0如2400等年份就是闰年嘛,还有就是他不能被100整除并且除4取余为0如:2008.2012以及去年2020等都是闰年,这两个满足一个就行(闰年寒假是不是多放一天。

了解了这些就有了下面的代码

if(b==2){
        if((a%400==0)||(a%100!=0&&a%4==0))
        {c=27+c;}
        else c=26+c;}//看下文

可以看出啊咱这里是以一个if-else选择语句来解决这个二月的问题,在这几行代码里面最.....,怎么说呢,最巧妙的就是判断到底是闰年的二月还是平年的二月之后的日期的推理。

当为闰年的二月时c=27+c;我们可以举栗子嘛:

3.1的前天为2.28,而28=27+1

3.2的前天为2.29,而29=28+1;当俺写到这的时候顿时冷汗直冒,真 牛 比(嘿嘿。

alt

通过这一个俺们应该就可以将所有的关于日期的特殊情况给写出来了(每月的1 . 2号)

不难看出

平年的二月为c=26+c

大月(不会的自己去幼儿园重开一把)(1.3.5.7.8.10.12,还是要说一下防止有些人手指头板错,手动滑稽x3嘿嘿)c=29+c

小月同理(4.6.9.11)c=c+28

于是就有了下面的代码

        else{if(b==4||b==6||b==9||b==11)
        {c=28+c;}
        else c=29+c;//这里的else是大月的情况

最后咱们再将他printf出来就可以了,注意哦printf里面也有陷阱,输出格式是yyyy-mm-nn的形式也就是说月和日要是为单数的话就必须在前面加个0才行

所以这里不用%d而用%02d(%d是整型输出格式,02的意思是如果输出的整型数不足两位左侧要用0来补,同样的年份的04也是同一个道理)。

问题到这里就分析的差不多了

alt

这些分析就是相当于一颗颗珍珠而我们现在就是要将他们穿成项链,穿完后完整代码如下:

#include<stdio.h>
int main()
{
    int a,b,c;
    scanf("%d-%d-%d",&a,&b,&c);
    if(c>2)
    { c=c-2;}
    else{b=b-1;
          if(b==0){
                   a=a-1;
                    b=12;}//判断普通年月日及12月份(暂时称为第一部分)
         
    if(b==2){
        if((a%400==0)||(a%100!=0&&a%4==0))
        {c=27+c;}
        else c=26+c;}//在判断闰年的同时将日期判断出来了
        else{if(b==4||b==6||b==9||b==11)//这部分else与第一部分并列这部分将除二月的1.2日
          //的前天判断出来(b!=2时与第一部分可判断具体日期)
        {c=28+c;}else c=29+c;
            }
        }
    printf("%04d-%02d-%02d",a,b,c);
  return 0;
}

你以为到这里我就结束了?这波你在第二层而我在第五层,你以为我要结束我其实还要bb,你以为我还要bb我直接反手一个结束,(手动滑稽x4.

alt

我为什么不结束呢,其实理由很简单,那就是有人会说:哎呀你的那步c=27+c谁想的到嘛。雀食,我当时也不知道怎么解释,但是当我写到一半时忽然a flash hit my head(散装英语)灵光一闪。下面解释

以闰年的二月为例闰年二月有29天(应该是),3.1号是2.29号的后一天,假设一年只有二月这一个月份那么,这个3.1号不正是相当于2.30号吗而2.30的前天不正是28号吗?而这个28,正是27+1即c=27+c。到这里是不是突然醍醐灌顶了。

说白了就是天数和月份之间存在着一种进制关系满多少进1,只需将这进制关系稍微还原一下就可以推出每个月的1.2号的前天了。

我p放完了,下面我再说一句:爷溜了(没想到吧。

观众们直呼::alt