目录
题目
题目链接:https://www.lanqiao.cn/problems/17113/learning/https://www.lanqiao.cn/problems/17113/learning/
思路和解题方法
1. 问题描述
小蓝计划在某天的日期中出现 时跑 千米,否则只跑 千米。注意日期中出现 不仅指年月日也指星期。
请问按照小蓝的计划, 年小蓝总共会跑步锻炼多少千米?例如, 月 日、 月 日、 月 日、 月 日 (星期一) 小蓝会跑 千米,而 月 日小蓝会跑 千米 (示例日期均为 年)
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
2. 解题思路
问题分析
首先对于题目,要求解的是 一年中,有多少天的月,日,星期中包含 。我们可以分为以下二步来求解问题。
日期模拟
首先我们要模拟 这一年每一年的情况。具体的,我们开一个月份数组,用来存储每一月的天数,然后从 年 月 日模拟到 年 月 日。
这里我们只模拟了月,日,对于星期,我们首先打开日历,查看 年 月 日是星期天,因此我们设置 week 初始值为 ,从 月 日开始模拟,然后每到新的一天,我们便将 week=week%7+1,便是当天是星期几,这样我们便完成了月,日,星期的模拟。
判断是否为
我们编写一个 cheek 函数,用来判断给定数字是否包含 ,正常循环拆解即可,最终对于月,日,星期,三者满足其一即是 +5。
最终结果为 。
附上我另一个以前写的日期问题(模板): 2017省赛---日期问题(暴力 枚举)
https://blog.csdn.net/jgk666666/article/details/130008471?
复杂度
时间复杂度:O(n)
O(n),其中n是年中的天数。
空间复杂度:O(1)
O(1),只使用了固定数量的额外空间。
c++ 代码
#include<bits/stdc++.h> // 包含C++常用的所有头文件
using namespace std; // 使用std命名空间,可以直接调用std下的函数和对象
typedef long long ll; // 定义ll为long long的类型别名,方便表示大整数
// 存储每个月的天数,数组第一个元素设为0方便索引(1月对应m[1])
int m[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
// 函数check,判断一个整数x的每一位是否包含数字1
bool check(int x){
while(x!=0){ // 循环直到x变为0
if(x%10==1) return true; // 如果x的最后一位是1,返回true
x/=10; // 去掉x的最后一个数字(整除10)
}
return false; // 如果循环结束都没有找到1,返回false
}
int main(){
int week=6; // 初始化星期变量为6,模拟1月1日是星期六
int ans=0; // 初始化答案变量为0,用于累计符合条件的日期数量
// 双重循环遍历一年中的所有月份(i)和日期(j)
for(int i=1; i<=12; i++){ // 遍历1到12月
for(int j=1; j<=m[i]; j++){ // 遍历当月的每一天
week=(week%7)+1; // 计算当前日期是星期几,模7加1模拟循环
// 判断条件:如果月份i、日期j或星期week包含数字1,则累计5
if(check(i)||check(j)||check(week)) ans+=5;
// 否则,累计1
else ans+=1;
}
}
// 输出累计的符合条件的日期数量
cout<<ans;
return 0; // 主函数正常结束
}
Java 版本
public class Main {
public static void main(String[] args) {
// 定义一个数组m,用于存储每个月的天数,考虑到简便性,索引0设置为0,实际数据从索引1开始
int[] m = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// 初始化变量week为6,模拟一周的第6天(即星期六),因为之后的计算中需要对星期进行循环更新
int week = 6;
// 初始化计数器ans为0,用于累计特殊日子的数量
int ans = 0;
// 双层循环遍历每个月(i)及其对应的天数(j)
for (int i = 1; i <= 12; i++) { // i代表月份
for (int j = 1; j <= m[i]; j++) { // j代表该月的每一天
// 更新week的值,使其循环表示星期(1-7分别代表周日到周六)
week = (week % 7 + 1);
// 使用check方法检查当前的月份i、日期j、以及星期week是否包含数字'1'
// 如果任何一个值包含数字'1',则视为特殊日子
if (check(i) || check(j) || check(week)) {
// 累加特殊日子的计数,每个特殊日子计为5
ans += 5;
} else {
// 非特殊日子,计数加1
ans += 1;
}
}
}
// 打印输出全年中特殊日子与非特殊日子累计的总分数
System.out.println(ans);
}
// 辅助方法:检查给定的数字x是否包含数字1
// 通过不断除以10并检查余数是否为1来实现
static boolean check(int x) {
// 循环直到数字x变为0
while (x != 0) {
// 如果x的最后一位(模10的结果)是1,返回true表示包含数字1
if (x % 10 == 1) {
return true;
}
// 去掉x的最后一个数字(除以10)
x /= 10;
}
// 如果循环结束没有找到数字1,返回false
return false;
}
}
Python 版本
# 定义一个函数用于检查给定的整数x的每一位数字是否包含1
def check(x):
# 循环直到x变为0
while x != 0:
# 如果x的个位数是1,返回True表示找到了1
if x % 10 == 1:
return True
# 将x除以10去掉个位数,继续检查下一位
x //= 10
# 如果循环结束没有找到1,返回False
return False
# 初始化答案计数器为0
ans = 0
# 定义一年中每个月的天数数组,注意二月默认为28天
m = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
# 双重循环遍历月份i(1到12)和日期j(1到当前月的最大天数)
for i in range(1, 13): # 遍历月份
for j in range(1, m[i] + 1): # 遍历当月的每一天
# 模拟每周的第一天递增,(week % 7 + 1)确保week始终在1到7之间循环表示周一到周日
week = (week % 7) + 1
# 检查当前的月份i、日期j、和周几week是否包含数字1
if check(i) or check(j) or check(week):
# 如果包含数字1,则当天视为特殊日子,累加5到答案中
ans += 5
else:
# 如果都不包含数字1,则普通日子,累加1到答案中
ans += 1
# 打印最终累加得到的答案,即特殊日子和普通日子的总计数
print(ans)
觉得有用的话可以点点赞,支持一下。
如果愿意的话关注一下。会对你有更多的帮助。
每天都会不定时更新哦 >人< 。