2023年蓝桥杯——日期统计

目录

[题目链接:1.日期统计 - 蓝桥云课 (lanqiao.cn)](#题目链接:1.日期统计 - 蓝桥云课 (lanqiao.cn))

题目描述

思路

代码思路

定义数据结构:

处理每一个月:

检查日期序列在num100中是否存在:

计数匹配的日期数:

输出结果:

代码实现

总结


题目链接:1.日期统计 - 蓝桥云课 (lanqiao.cn)

题目描述

小蓝现在有一个长度为 100 的数组,数组中的每个元素的值都在 0到9的范围之内。数组中的元素从左至右如下所示

5 6 8 6 9 1 6 1 2 4 9 1 9 8 2 3 6 4 7 7 5 9 5 0 3 8 7 5 8 1 5 8 6 1 8 3 0 3 7 9 2 7 0 5 8 8 5 7 0 9 9 1 9 4 4 6 8 6 3 3 8 5 1 6 3 4 6 7 0 7 8 2 7 6 8 9 5 6 5 6 1 4 0 1 0 0 9 4 8 0 9 1 2 8 5 0 2 5 3 3

现在他想要从这个数组中寻找一些满足以下条件的子序列:

1.子序列的长度为 8

2.这个子序列可以按照下标顺序组成一个yyyymmdd 格式的日期,并且要求这个日期是 2023 年中的某一天的日期,例如20230902,20231223。yyyy表示年份,mm 表示月份,dd 表示天数,当月份或者天数的长度只有一位时需要一个前导零补充。

请你帮小蓝计算下按上述条件一共能找到多少个不同的 2023 年的日期。对于相同的日期你只需要统计一次即可。


思路

这题就是一个老六题!!!!!!!!!!!!!!!!!!!!!!!!!!!!

我一开始以为是要找一个连续的子序列,md然后一直过不了,甚至跑出来的答案是0,wdf!!!玩神魔,结果我又读了好几遍题目,这也没说是连续的子序列啊,于是我的代码就没有去找连续的子数列,好家伙,终于拿下了,服了,废了,倦了。

代码思路

定义数据结构
  • mday数组存储了不同月份的天数,其中二月份由于是2023非闰年,所以是28天。
  • num100数组包含一组100个整数,用于与日期的每一位进行比对。
  • nowTime数组初始值为20230000,用于表示日期序列,格式为YYYYMMDD
处理每一个月
  • 通过两重循环遍历一年中的每一天。外层循环代表月份i,内层循环代表对应月份的天数j
  • 为了构造当前日期,nowTime数组需要根据循环变量ij更新代表月和日的部分。
  • 月份的十位和个位分别由i / 10i % 10给出,存储到nowTime[4]nowTime[5]中。
  • 日期的十位和个位由j / 10j % 10给出,存储到nowTime[6]nowTime[7]中。
检查日期序列在num100中是否存在
  • 对于每个nowTime所表示的日期,调用checkHave函数来检查这个日期序列是否在num100数组中以非连续形式出现。
  • checkHave函数通过两个指针p100pnow分别在num100nowTime上移动。
  • 如果两个指针所指元素相同,则两个指针都往前移动;如果不同,那么只移动num100的指针。
  • 如果pnow达到8,说明nowTime的所有数字都在num100中顺序出现过了,这时函数返回1。
  • 否则,如果在num100遍历完毕还未找到匹配,返回0。
计数匹配的日期数
  • 主循环里面会累加checkHave函数的返回值到变量res中。
  • 每次成功匹配(找到nowTime中的日期序列在num100中以非连续形式存在),计数器res增加1。
输出结果
  • 最后,输出的res变量表示在一年中发现的符合条件的日期数。

代码实现

java 复制代码
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
	public static void main(String[] args) {
		// 存储不同月份的天数
		int[] mday = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
		int[] num100 = { 5, 6, 8, 6, 9, 1, 6, 1, 2, 4, 9, 1, 9, 8, 2, 3, 6, 4, 7, 7, 5, 9, 5, 0, 3, 8, 7, 5, 8, 1, 5, 8, 6,
				1, 8, 3, 0, 3, 7, 9, 2, 7, 0, 5, 8, 8, 5, 7, 0, 9, 9, 1, 9, 4, 4, 6, 8, 6, 3, 3, 8, 5, 1, 6, 3, 4, 6, 7,
				0, 7, 8, 2, 7, 6, 8, 9, 5, 6, 5, 6, 1, 4, 0, 1, 0, 0, 9, 4, 8, 0, 9, 1, 2, 8, 5, 0, 2, 5, 3, 3 };
		// 初始数据
		int[] nowTime = { 2, 0, 2, 3, 0, 0, 0, 0 };
		// res
		int res = 0;
		for (int i = 1; i <= 12; i++) {
			// 获得月份
			// 如果是十月之后,那么格式就是1x的格式
			nowTime[4] = i / 10;
			// 取模得最后一位
			nowTime[5] = i % 10;

			// 获得天数
			for (int j = 1; j <= mday[i]; j++) {
				// 取左边的数
				nowTime[6] = j / 10;
				// 取右边的数
				nowTime[7] = j % 10;
				
				res += checkHave(num100, nowTime);
			}
		}
		System.out.println(res);
	}

	
	public static int checkHave(int[] num100, int[] nowTime) {
		// 定义出,两个指针,分别判断100个数和当前的序列样子
		int p100 = 0;
		int pnow = 0;
		while (p100 < 100 && pnow < 8) {
			if (num100[p100] == nowTime[pnow]) {
				// 如果当前位置对上了
				p100++;
				pnow++;
			}else {
				// 没对上
				p100++;
			}
		}
		return pnow == 8 ? 1 : 0;
	}
}

这里的checkHave函数实际上是在检查nowTime数组中的数字序列是否在另一个较长的num100数组中以任意顺序出现(不必连续)。这意味着只要nowTime数组的所有元素都在num100数组中按顺序出现(不必相邻),就会返回1,表明匹配成功;否则,返回0表示没有找到匹配的序列。

checkHave函数逐个比较nowTime数组中的数字,与num100数组中的数字进行匹配。只要找到匹配的数字,就同时将两个数组的指针向前移动,依次检查nowTime数组中的下一个数字。如果num100中的数字与nowTime当前位置的数字不匹配,则只移动num100的指针,继续搜索下一个可能匹配的数字。当nowTime数组中的所有元素都成功匹配时,即pnow达到数组的长度时,函数返回1;如果num100数组已遍历完成但未找到完全匹配的序列,则返回0。

整个主程序的逻辑是生成一个日期序列,并检查这个序列在num100数组中以任意顺序是否出现过。如果出现过,则计数加一。最后输出这个计数,表示在一年的日期中有多少个是在num100中可以找到匹配的序列的。


总结

我真的服啦,这老六题目真的有时候能不能描述™清楚一点啊,我*****

相关推荐
JavaGuide17 分钟前
JDK 25(长期支持版) 发布,新特性解读!
java·后端
用户37215742613518 分钟前
Java 轻松批量替换 Word 文档文字内容
java
白鲸开源19 分钟前
教你数分钟内创建并运行一个 DolphinScheduler Workflow!
java
CoovallyAIHub1 小时前
中科大DSAI Lab团队多篇论文入选ICCV 2025,推动三维视觉与泛化感知技术突破
深度学习·算法·计算机视觉
Java中文社群1 小时前
有点意思!Java8后最有用新特性排行榜!
java·后端·面试
代码匠心1 小时前
从零开始学Flink:数据源
java·大数据·后端·flink
间彧1 小时前
Spring Boot项目中如何自定义线程池
java
间彧2 小时前
Java线程池详解与实战指南
java
用户298698530142 小时前
Java 使用 Spire.PDF 将PDF文档转换为Word格式
java·后端
NAGNIP2 小时前
Serverless 架构下的大模型框架落地实践
算法·架构