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

川长思鸟来 2021-07-24 19:56 750阅读 0赞

题目

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

思路

我们首先写一个判断日期是否合法的函数check,这个函数用来检查一个八位的日期是否合法。

模板如下

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

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

然后我们枚举日期20000101到日期20201001,筛选出合法的日期。这里有一个难点,如何判断某一天是星期几?其实我们可以发现星期几是和这天是几号无关的,因为一周七天,每七天一轮回,该天是星期几取决于起始日期是星期几和该天离起始日期多少天。假设终点日期离起始日期sum天,起始日期是星期六,我们只需(sum + 6) % 7 == 1就可以轻松判断出这天是不是星期一。(sum + 6) % 7 == 0代表星期日,其余一 一对应。我们带一个特殊日期验证一下,假设终点日期是起始日期,sum==0(0 + 6) % 7 == 6 ,验证无误,当然如果不放心的话可以多带几个日期验证一下。

答案: 8879

代码

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. using namespace std;
  5. int months[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31};
  6. bool check(int date)
  7. {
  8. int year = date / 10000;
  9. int month = date % 10000 / 100;
  10. int day = date % 100;
  11. if(!month || month > 12 || !day ) return false;//
  12. if(month != 2 && day > months[month]) return false;
  13. if(month == 2)
  14. {
  15. if((year % 4 == 0&& year % 100 != 0) || (year % 400 == 0))
  16. {
  17. if(day > 29) return false;
  18. }
  19. else if( day > 28) return false;
  20. }
  21. return true;
  22. }
  23. int main()
  24. {
  25. int res = 0,sum = 0;//sum记录相隔天数,res记录答案
  26. for(int i = 20000101; i <= 20201001; i++) // 1 2 3
  27. {
  28. if(check(i))
  29. {
  30. res ++ ;
  31. int month = i % 10000 / 100;
  32. int day = i % 100;
  33. if( day == 1 || (sum + 6) % 7 == 1 ) res++; //周一或月初,加一千米
  34. sum ++ ;
  35. }
  36. }
  37. cout<<res<<endl;
  38. return 0;
  39. }

发表评论

表情:
评论列表 (有 0 条评论,750人围观)

还没有评论,来说两句吧...

相关阅读