一、题目要求如下
二、解题思路
解读题意:
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;
}