天天看點

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;
}
           

繼續閱讀