蓝桥杯:跑步锻炼算法题(java)
该文章仅供参考,因为博主很菜,所以方法很笨,望大佬们提出宝贵的意见!!!谢谢!!!
原题目
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
小蓝每天都锻炼身体。
正常情况下,小蓝每天跑 1 千米。如果某天是周一或者月初(1 日),为了激励自己,小蓝要跑 2 千米。如果同时是周一或月初,小蓝也是跑 2 千米。
小蓝跑步已经坚持了很长时间,从 2000 年 1 月 1 日周六(含)到 2020 年 10 月 1 日周四(含)。请问这段时间小蓝总共跑步多少千米?
运行限制
最大运行时间:1s
最大运行内存: 128M
思路解析
在本文中,该算法题的结果可以分为三部分:
- 第一部分:小蓝每天跑1公里的总里程(相当于总天数)
- 第二部分:小蓝每个月初多跑1公里的总里程
- 第三部分:小蓝每周一多跑1公里的总里程(不包括月初)
所以,在该题中额外需要注意的点就是:
当一天既是月初又为周一时,不能将该天多跑的里程加两次!!!
对应于思路,我们需要求解的变量就有了:
- 需要找到从2000年1月1日到2020年10月1日每个月的月初;
- 需要找到从2000年1月1日到2020年10月1日每周的周一;
- 要有这20年的总天数;
- 需要找到既是月初又是周一的天数;
原答案(不建议观看)
虽然写的很烂,但还是厚着脸皮放出来吧。。。
没有经过整理的原答案,没有函数,很臃肿,但确实是写对了,
可能会对读者有点启发:
import java.util.Scanner;
import java.util.ArrayList;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//在此输入您的代码...
//该list集合用于存储每个月的月初
ArrayList<Integer> list = new ArrayList<>();
int sum = 1; //记录总天数,初始值为1表示2000年1月1日已经计算在内
int ans = 1; //总里程,1表示2000年1月1日已经多跑了1公里(月初)
//第一部分:每个月初多跑一公里
for(int i = 2000; i <= 2020;i++){
//根据每个月天数相加
sum += 31;
ans++; //多跑了一公里
list.add(sum);
//这里简略判断了闰年,当年数变化以后可能不好使
if(i % 4 == 0){
sum += 29;
}else{
sum += 28;
}
list.add(sum);
ans++;
sum += 31;
list.add(sum);
ans++;
sum += 30;
list.add(sum);
ans++;
sum += 31;
list.add(sum);
ans++;
sum += 30;
list.add(sum);
ans++;
sum += 31;
list.add(sum);
ans++;
sum += 31;
list.add(sum);
ans++;
sum += 30;
list.add(sum);
ans++;
//截止到2020年10月1日
if(i != 2020){
sum += 31;
list.add(sum);
ans++;
sum += 30;
list.add(sum);
ans++;
sum += 31;
list.add(sum);
ans++;
}
}
//第二部分:每天跑1公里的总里程
ans += sum;
//第三部分:每周一多跑1公里,并剔除掉月初,防止重复计算。
for(int i = 3;i < sum;i += 7){
if(list.contains(i)){
continue;
}
ans++;
}
//输出结果
System.out.println(ans);
scan.close();
}
}
由于原答案比较烂,所以注释就不写那么详细了,大家可以看整理后的答案。
经过整理后的答案
- 将12个月的天数使用一个数组进行封装;
- 将判断闰年单独写一个函数;
- ArrayList集合用于存储每个月的月初;
- num表示总天数,初始值为1表示2000年1月1日已经计算在内;
- ans表示总里程,初始值为1表示2000年1月1日月初已经多跑了1公里;
- ans++表示月初或周一多跑了一公里。
import java.util.ArrayList;
public class Main{
public static void main(String[] args){
//初始化月份天数,二月份天数会进行额外处理
int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
//新建一个集合,该集合中用于存储所有月初天数
ArrayList<Integer> list = new ArrayList<>();
int num = 1; //表示从2000年1月1日到2020年10月1日经历的总天数,初始值为1表示2000年1月1日已经被计算在内。
int ans = 1; //表示总里程,即答案的结果。初始值为1表示2000年1月1日多跑1千米。
for(int i = 2000;i <= 2020;i++) {
monthDays[1] = 28;
//判断该年是否为闰年,若为闰年2月份为29天
if(isLeapYear(i)){
monthDays[1] = 29;
}
for(int j = 0;j < monthDays.length;j++){
//若已经到了2020年10月1日,退出循环
if(i == 2020 && j == 9) break;
num += monthDays[j]; //总天数
list.add(num); //将月初加入集合中
//若为月初,总里程多跑1千米;
ans++;
}
}
/*
循环结束后,分析一下变量的值:
list:list中包含了所有从2000年1月1日到2020年10月1日中的月初所经历的天数。
num:num的值为2020年1月1日(含)到2020年10月1日(含)的总天数。
ans:所有月初多跑的里程已经计算在内。
*/
ans += num; //每天跑1千米
/**
* 计算每周一多跑的1千米,并且若为月初,不需要重复计算。
*/
//因为第1天为周六,所以周一从第3天开始。
for(int i = 3;i < num;i += 7){
//若为月初,直接跳过,不要重复计算。
if(list.contains(i)){
continue;
}
ans++;
}
//输出结果
System.out.println(ans);
}
/**
* 判断该年是否为闰年
*/
public static boolean isLeapYear(int year){
return (year % 400 == 0 || year % 4 == 0 && year % 100 != 0);
}
}
运行结果
感谢大家艰难的看完了我的思路!
欢迎大家提出意见!