蓝桥杯C语言练习题目(九)---- 跑步锻炼

文章介绍了一个编程问题,涉及从2000.1.1到2020.10.1的日期范围内,按特定规则(如闰年、大月、小月等)计算每日跑步公里数。通过判断闰年、月份天数和星期几,确定每月月初和周一的额外跑步量。最终通过while循环实现总跑步距离的计算。
摘要由CSDN通过智能技术生成

一、题目要求如下

二、解题思路

解读题意:

        1、从2000.1.1(周六)开始跑步,跑到2020.10.1(周四)

        2、每天跑1km,月初跑2km,周一跑2km

        3、因为要考虑每个月大小不同,就要考虑大小月,就要考虑闰平年

回顾一下闰年知识:

        当一个年份可以被400整除就被称为世纪闰年,2月=29天

        当一个年份可以被4整除但不能被100整除就为普通闰年,2月=29天

        其他情况的年份,都是平年。2月=28天

无论是世纪闰年还是普通闰年都是2月=29天。通过以上要求可以得到判断是否是闰年的式子

year%4==0 && year%100!=0 || year%400==0

 year%4==0就是能被4整除,&& 为 与运算符,等于中文中的“且”字。

        year%4==0 && year%100!=0的含义就为:能被4整除且不能被100整除

|| 为 或运算符,等于“或”字。

        || year%400==0 的含义:或者满足年份能被400整除

由此我们知道如何判断年份是否为闰年。

然后我们又如何知道月份是哪个月呢,大小月头疼?

这个不难,用最简单的方法,分别判断 ( || 大法)

mon为月份,若月份等于1或3或5.....总之月份等于其中一个数字,就整个判断都等于成立

如果月份是1、3、5、7、8、10、12,就是大月,有31天。

我这边设置了个k,k的含义是:当前月份=最大月份减去k天。31-k天,若为大月,k就为0,31-k就还是31天

若月份是小月,则k等于1;  31-1为30天,满足小月天数。

若月份是二月呢,k要赋值多少? 31-k等于我们想要的天数。

对,当年份是闰年,且是二月份的时候,k就是2。31-2=29天

当年份是平年,二月就是28天,k就等于3;

除了以上情况,如果还不满足,说明月份不合法了,也就是13月。所以else语句存放的是当月份为13月的时候该做的措施。----月份重置成1月;年份+1;

紧接着后面就是while循环,主要作用是累加跑步数和当前月份的天数。

怎么判断是否为星期1呢?

设置一个week_day【】数组,里面存放1、2、3、4、5、6、7,再设置一个n来记录下标

因为2000.1.1是星期六,所以n的初值为5(6的下标是5)

然后我们只需要每次跑完步后都让n+1,那怎么实现让他重复而不是无线累加上去呢?

每次跑完步都有个这样的语句: n=(n+1)%7

这句话的含义就是:让n+1后跟7取余数,若当前n=6,取余就是6,当n=7,取余就是0,最后再将n赋值给自身。就实现了n到7就自动变成0的功能。

我们整个框架就是这样的:

while(日期还没到2020.10.1就执行以下语句){

        if(月份合法){赋值对应月份的k值;}

        else  {月份变成1月;年份+1; }

        while(当前月份的日期合法){

                判断星期几、是否为月初、若满足月初和星期一就 执行{km+=2;n=(n+1)%7;}

                若是普通的一天,就执行{km+=1;n=(n+1)%7;}

                日期自加1;

        }

        月份自加1;

}

km+=2;

三、代码实现

mon_date是当前月的第几天。例如:mon_date=2,说明是当前月份的2号

#include <stdio.h>
int main()
{
  // 请在此输入您的代码
  int year=2000,mon=1,mon_date=1,week_day[]={1,2,3,4,5,6,7},km=0,k,n=5;

  while(year!=2020 || mon!=10 || mon_date!=1){

    //判断月份,k为最大月份应减去的数字。例如 k=2,说明该月份最大日期应该是31-2
    if(mon==1 || mon==3 || mon==5 || mon==7 || mon==8 || mon==10 || mon==12) k=0;
    else if(mon==4 || mon==6 || mon==9 || mon==11) k=1;
    else if(mon==2 && (year%4==0&&year%100!=0 || year%400==0)) k=2;
    else if(mon==2) k=3;

	  //若月份超过12月,重置为1。并且年份累加1
    else {mon=1;year+=1;}

    //累加日期模块,date为一共过了多少天,mon_date为这个月过了多少天
    while(mon_date <= 31-k){
      //当过了的天数对7取模+4 等于1,则判定为周一。若mon_date为0,则判定为月初
      if(week_day[n]==1) {km+=2;n=(n+1)%7;}
      else if(mon_date==1) {km+=2;n=(n+1)%7;}
      else {km+=1;n=(n+1)%7;}//除了月初和周一。其他时候跑1km
      
      mon_date+=1;
    }
  
    //一旦月份日期超过31-k,则将月份日期重置为0.并且月份累加1;
    mon_date=1;
    mon+=1;
  }
  km+=2;

  printf("%d",km);
  return 0;
}

-----------------------------------------------------------------------------------

码题不易,跪求点赞!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值