目录
题目链接:11.特殊日期 - 蓝桥云课 (lanqiao.cn)
题目链接:11.特殊日期 - 蓝桥云课 (lanqiao.cn)
思路
蓝桥杯好像经常出这种题目,特殊日期的题目其实都有特殊的模版,如果写过的话那么在比赛的时候遇到会非常的easy就解决掉,但是如果没有做过的话,可能要思考一些时间,而且容易掉到一些坑里。
暴力
代码细节
数据准备与初始化
代码首先初始化两个数组pMonths
和rMonths
,分别存储平年和闰年每月的天数。然后设定一个变量res
记录满足条件的日期数量。
对于所有的年份(2000年至1999999年),代码将根据具体的年份来决定选取pMonths
还是rMonths
。判断闰年的条件是"能被4整除但不能被100整除"或者"能被400整除"。
主循环结构
代码主要包含三层循环结构:年,月和日。对每一年的每一月的每一天,判断日期是否满足年份是月份和日期的倍数的条件。如果满足,就使res
自增1。这样可以统计出满足条件的所有日期的总数。
结果输出
在循环结束后,将变量res
的值加1(以包括2000000年1月1日这一天),并输出这个结果。
运行说明
这个程序比较耗时,尤其是在循环大量年份时。为了方便,可以在本地编译器运行获取结果,并直接输出,这里的System.out.println(35813062 + 1);
就是这个目的,其中的数字35813062
是预先运算得出的结果。
代码实现
Java
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static int[] pMonths = {0,31,28,31,30,31,30,31,31,30,31,30,31};
public static int[] rMonths = {0,31,29,31,30,31,30,31,31,30,31,30,31};
// 1 2 3 4 5 6 7 8 9 10 11 12
public static void main(String[] args) {
int res = 0;
// 年份
for (int i = 2000; i <= 1999999; i++) {
// 判断是平年还是闰年
int[] mon = pMonths;
if ((i % 4 == 0 && i % 100 != 0) || i % 400 == 0) {
// 是闰年
mon = rMonths;
}
// 月份
for (int j = 1; j <= 12; j++) {
// 天
for (int k = 1; k <= mon[j]; k++) {
// 到这里就是i表示年份,j表示月份,k表示一个月份中的天数
// 现在需要判断该日期满足i是j和k的倍数
if (i % j == 0 && i % k == 0 ) {
res++;
}
}
}
}
// 这里是填空题,可能会超时,所以可以在本地编译器跑出来然后直接输出
// 这里 +1 是为了将2000000年一月一日的日期加上
System.out.println(35813062 + 1);
}
}
C++
#include <iostream>
#include <vector>
using namespace std;
vector<int> pM = {0,31,28,31,30,31,30,31,31,30,31,30,31};
vector<int> rM = {0,31,29,31,30,31,30,31,31,30,31,30,31};
int main()
{
int res = 0;
// 年份
for(int i = 2000; i <= 1999999; i++){
// 判断是平年还是闰年
vector<int> mon = pM;
if((i % 4 == 0 && i % 100 != 0) || i % 400 == 0){
mon = rM;
}
// 月份
for(int j = 1; j <= 12; j++){
// 该月份的天
for(int k = 1; k <= mon[j]; k++){
if(i % j == 0 && i % k == 0){
res++;
}
}
}
}
cout << res + 1;
return 0;
}
总结
注意开始年份和结束年份的边界问题,注意开始的月份天数数组的处理。
好了加油吧家人们。^_^