天天看点

2020年第十一届蓝桥杯省赛c/c++b组 跑步锻炼 【c++详细题解】

题目

小蓝每天都锻炼身体。

正常情况下,小蓝每天跑 1 千米。如果某天是周一或者月初(1 日),为了激励自己,小蓝要跑 2 千米。如果同时是周一或月初,小蓝也是跑 2 千米。小蓝跑步已经坚持了很长时间,从 2000 年 1 月 1 日周六(含)到 2020 年10 月 1 日周四(含)。请问这段时间小蓝总共跑步多少千米?

思路

我们首先写一个判断日期是否合法的函数

check

,这个函数用来检查一个八位的日期是否合法。

模板如下

int months[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
bool check(int date)
{
    int year = date / 10000;  //年
    int month = date % 10000 / 100;  //月
    int day = date % 100;  //日
    if(!month || month > 12 || !day )  return false;//如果月份大于12或者为零或者天数为零则该日期不合法
    if(month != 2 && day > months[month]) return false;//在不是二月的情况下,该月实际天数大于该月最大天数,则该日期不合法
    if(month == 2) //特判二月
    {
        if((year % 4 == 0&& year % 100 != 0) || (year % 400 == 0))//特判闰年
        {
            if(day > 29) return false;
        }
        else if( day > 28) return false;
    }
    return true;
}
           

这个模板要牢记,几乎可以套所有的日期模拟题,尤其对这种填空题,可以说是大杀器。

然后我们枚举日期

20000101

到日期

20201001

,筛选出合法的日期。这里有一个难点,如何判断某一天是星期几?其实我们可以发现星期几是和这天是几号无关的,因为一周七天,每七天一轮回,该天是星期几取决于起始日期是星期几和该天离起始日期多少天。假设终点日期离起始日期

sum

天,起始日期是星期六,我们只需

(sum + 6) % 7 == 1

就可以轻松判断出这天是不是星期一。

(sum + 6) % 7 == 0

代表星期日,其余一 一对应。我们带一个特殊日期验证一下,假设终点日期是起始日期,

sum==0

(0 + 6) % 7 == 6

,验证无误,当然如果不放心的话可以多带几个日期验证一下。

答案: 8879

代码

#include<iostream>
#include<cstdio>
#include<algorithm> 

using namespace std;
int months[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
bool check(int date)
{
    int year = date / 10000;
    int month = date % 10000 / 100;
    int day = date % 100;
    if(!month || month > 12 || !day )  return false;//
    if(month != 2 && day > months[month]) return false;
    if(month == 2)
    {
        if((year % 4 == 0&& year % 100 != 0) || (year % 400 == 0))
        {
            if(day > 29) return false;
        }
        else if( day > 28) return false;
    }
    return true;
}
int main()
{
	int res = 0,sum = 0;//sum记录相隔天数,res记录答案
	for(int i = 20000101; i <= 20201001; i++)   // 1 2 3 
	{
		if(check(i))
		{
		    res ++ ;
		    int month = i % 10000 / 100;
		    int day = i % 100;
			if( day == 1 || (sum + 6) % 7 == 1 )   res++; //周一或月初,加一千米
			sum ++ ;   
		}
	}
	cout<<res<<endl;
	return 0;
}
           

继续阅读