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中可以找到匹配的序列的。


总结

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

相关推荐
学java的小菜鸟啊10 分钟前
第五章 网络编程 TCP/UDP/Socket
java·开发语言·网络·数据结构·网络协议·tcp/ip·udp
zheeez14 分钟前
微服务注册中⼼2
java·微服务·nacos·架构
程序员-珍18 分钟前
SpringBoot v2.6.13 整合 swagger
java·spring boot·后端
徐*红25 分钟前
springboot使用minio(8.5.11)
java·spring boot·spring
聆听HJ26 分钟前
java 解析excel
java·开发语言·excel
AntDreamer30 分钟前
在实际开发中,如何根据项目需求调整 RecyclerView 的缓存策略?
android·java·缓存·面试·性能优化·kotlin
java_heartLake34 分钟前
设计模式之建造者模式
java·设计模式·建造者模式
G皮T35 分钟前
【设计模式】创建型模式(四):建造者模式
java·设计模式·编程·建造者模式·builder·建造者
niceffking39 分钟前
JVM HotSpot 虚拟机: 对象的创建, 内存布局和访问定位
java·jvm
菜鸟求带飞_42 分钟前
算法打卡:第十一章 图论part01
java·数据结构·算法