2025年第十六届蓝桥杯省赛JavaB组真题回顾

2025年第十六届蓝桥杯省赛JavaB组真题回顾

 第16届蓝桥杯省赛已经结束了,第一次参加也是坐牢了4个小时,现在还是来总结一下吧(先声明以下的解法,大家可以当作一种思路来看,解法不一定是正解,只是给大家提供一种能够正常想到的思路吧)

试题A:逃离高塔

本题其实没有什么难度,就是一个循环遍历即可,那么唯一需要注意的就是循环遍历的过程中,int是会爆的,这里需要用long来进行存储
public class Main{ public static void main(String[] args){ int ans=0;//记录最终答案 for(long i=1;i<=2025;i++){ long x=i*i*i; if(n%10==3){ ans++; } } System.out.println(ans); } } ​
 最后进行的答案就是:202

 试题B:消失的蓝宝

这题其实也是循环遍历即可,但是我们不能一个数一个数的去试,如果一个一个去遍历的话,好像是要跑2小时是可以跑出来,那么通过题目我们可以发现:N+20250412要能够被20240413整除N+20240413要能够被20250412整除

上述表达式我们可以理解为,这个数一定是20240413的倍数,并且可以发现20250412比20240413是要大9999,那么我们可以设一个数 n1 初始为20240413,然后循环从20240413开始遍历,n1 每次都加上一个20240413(因为最后的结果一定是20240413的倍数,所以其他数就没有必要一个一个去遍历了),然后再循环中我们定义 n2=n1-9999,然后判断如果当前的 n2%20250412==0?(我们每次加的都是20240413,这个数肯定是20240413的倍数,则无需再判断n1%20240413==0?),如果等于0那么再减去一个20250412就是最终答案!(因为我们是第一个表达式为基准的,所以要减去一个20250412)
public class Main{ public static void main(String[] args){ for(long n1=20240413L;n1<Long.MAX_VALUE;n1+=20240413){ long n2=n1-9999; //判断 if(n2%20250412==0){ System.out.println(n1-20250412); break; } } } } 
最终答案就是:409876661809331 

 试题C:电池分组

这题就是一个位运算判断:要求将若干个数分为2组数字,那么这两组数字的异或和结果一样的话,一定是等于0的,这是为啥呢?举个例子:

例如样例的 1 2 3,1和2进行异或和后是3,那么3^3不就是0吗?所以我们只需要遍历一遍数组看看最后的异或结果是不是0即可(偷偷抱怨:这题这是太可惜了,考前1周都在学动态规划,考场看到这题还以为是01背包的选与不选的变种问题,最后还没写出来!!!)
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scan=new Scanner(System.in); int t=scan.nextInt(); while(t-->0){ int n=scan.nextInt(); int ans=0; for(int i=0;i<n;i++){ ans^=scan.nextInt(); } if(ans==0){ System.out.println("YES"); }else{ System.out.println("NO"); } } } } 

 试题D:魔法科考试

这题的考点就是判断素数的问题,其实就是两个循环遍历两个数组然后判断条件是否成立(需要的注意的是,这里会重复计算条件成立的同一个数,那么应该Set来过滤重复的数),再一个就是性能的问题,这里的数据是20000,如果使用朴素方法判断一个数是不是素数,那么最坏情况的时间复杂度就是n*m*log(a[i]+b[j]),这个时间复杂度是决定会超时的,在洛谷上这个时间复杂度是只能过8个案例的,所以我们应该提前筛好素数,然后在O(1)的时间复杂度判断是不是素数!(考场上我也没注意,使用的就是朴素的判断素数,这题也是拿不满的,可惜!!!)
import java.util.HashSet; import java.util.Scanner; import java.util.Set; public class Main{ static int[]prime=new int[20005]; static boolean st[]=new boolean[20005]; static int cnt=0; static Set<Integer> set=new HashSet<>(); static int num; public static void main(String[] args){ Scanner scan=new Scanner(System.in); int n=scan.nextInt(); int m=scan.nextInt(); int []a=new int[n]; int []b=new int[m]; for(int i=0;i<n;i++){ a[i]=scan.nextInt(); } for(int i=0;i<m;i++){ b[i]=scan.nextInt(); } num=n+m; //筛素数 creat(); //遍历枚举 int ans=0;//记录最终答案 for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ int s=a[i]+b[j]; if(s<=num){ //判断是不是素数 if(set.contains(s)){ ans++; set.remove(s); } } } } System.out.println(ans); } public static void creat(){ //这是只需要筛选出num以内的素数即可,因为超过num的素数我们根本判断不到 for(int i=2;i<=num;i++){ if(!st[i]){ prime[cnt++]=i; set.add(i); } for(int j=0;j<cnt;j++){ if(i*prime[j]>num)break; st[i*prime[j]]=true; if(i%prime[j]==0)break; } } } }

试题E:爆破

本题的核心就是在于,如何知道两个圆的最短距离:两个圆心之间的距离减去两个圆各自的半径,如果<=0那么就是相交的,如果不是那么就不是相交的

 画图分析:(画图画的不好请见谅)

import java.util.Scanner; public class Main{ static int g[][]; public static void main(String[] args) { Scanner scan=new Scanner(System.in); int n=scan.nextInt(); g=new int[n+1][3]; for(int i=1;i<=n;i++){ g[i][0]=scan.nextInt(); g[i][1]=scan.nextInt(); g[i][2]=scan.nextInt(); } //创建n*n的表格 double dp[][]=new double[n+1][n+1];//dp[i][j]表示第i个圆和第j个圆之间的距离 double ans=0;//存放最后答案 for(int i=1;i<=n;i++){ double min=Double.MAX_EXPONENT;//寻找当前圆和其他圆的最小距离 for(int j=1;j<=n;j++){ //判断第i个圆和第j个圆的距离 //先判断是不是自身 if(i==j){ dp[i][j]=Double.MAX_EXPONENT;//因为我们最后要求一个最小的值,所以这里赋最大值 }else{ dp[i][j]=func(i,j); } min=Math.min(min,dp[i][j]); } ans+=min; } System.out.printf("%.2f",ans); } //判断距离 public static double func(int i,int j) { //如果横坐标相同,直接判断纵坐标距离 if(g[i][0]==g[j][0]){ int len=Math.abs(g[i][1]-g[j][1]);//得到两个圆心的距离,再减去两个半径 len=len-(g[i][2]+g[j][2]); //判断是不是小于0.小于0就是相交的,距离就是0 return len<=0?0:len; } //如果纵坐标相同,直接判断横坐标的距离 if(g[i][1]==g[j][1]){ int len=Math.abs(g[i][0]-g[j][0]);//得到两个圆心的距离,再减去两个半径 len=len-(g[i][2]+g[j][2]); //判断是不是小于0.小于0就是相交的,距离就是0 return len<=0?0:len; } //此时是横纵坐标都不在一条线上,需要利用横纵坐标来结合勾股定理来得到两个圆心的距离 //我们以直角为基准,求两个临边的长度,然后通过勾股定理来求出对边(斜边)的长度 int lenx=Math.abs(g[i][0]-g[j][0]); int leny=Math.abs(g[i][1]-g[j][1]); //勾股 double len=Math.sqrt(lenx*lenx+leny*leny); //此时得到两个圆心的位置,然后再减去两个圆的半径 len=len-(g[i][2]+g[j][2]); return len<=0?0:len; } } 

试题F:数组翻转

本题呢本质上来说就是找两个最大的连续区间,暴力+优化

根据样例分析:

4 4 3 3 2 1 3 以样例为例就是最后变成4 4 3 3 3 1 2

那我们可以拓展一下 4 4 3 3 2 1 3 3 4 4 4

那就是4 4 4 4 4 3 3 1 2 3 3

我们会发现翻转的最佳效果是把连续并且相同的数最大的和第二大的合并在一起

 以下代码是暴力解法可能是会超时的(如果后续有更好的想法再做更新吧)

import java.util.Scanner; public class Main{ static boolean st[];//判断当前数是不是查找过 public static void main(String[] args) { Scanner scan=new Scanner(System.in); int n=scan.nextInt(); int[]a=new int[n]; int max=0; for(int i=0;i<n;i++){ a[i]=scan.nextInt(); max=Math.max(a[i],max); } st=new boolean[max+1]; long ans=0;//记录最终答案 for(int i=0;i<n;i++){ if(st[a[i]])continue;//此时说明当前数判断过了 int max1=0;//记录第一长的区间长度 int max2=0;//记录第二长的区间长度 int cnt=0; for(int j=i;j<n;j++){ if(a[j]==a[i]){ cnt++; }else{ //如果不是,那么我们记录一下之前的长度 if(cnt>max1){ max2=max1; max1=cnt; }else if(cnt>max2){ max2=cnt; } cnt=0; } } if(cnt!=0){ if(cnt>max1){ max2=max1; max1=cnt; }else if(cnt>max2){ max2=cnt; } } st[a[i]]=true; //此时统计两个最长区间 ans=Math.max(ans,1l*a[i]*(max1+max2)); } System.out.println(ans); } } 

试题G:2的幂

 本题暂时没有什么好的思路就先:略(如果有佬有想法可以评论在评论区)
... 

 

试题H:研发资源分配

 

这题读完题目感觉就是一个全排列求最大价值问题,但是直接dfs肯定是会超时的(只能过20%的案例),所以可以试试贪心策略,为了使 A 部门获得的资源尽可能多,B 部门获得的资源尽可能少,每天都让 A 部门提交比 B 部门当天提交等级刚好大 1 的等级(如果存在),如果没有更大的等级,就选择最小的等级,避免资源作废。如果都选择不了,那么就只能判断相等的数能不能相互抵消了
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); int[] b = new int[n]; for (int i = 0; i < n; i++) { b[i] = scanner.nextInt(); } boolean[] used = new boolean[n + 1]; int sumA = 0; int sumB = 0; for(int i=0;i<n;i++){ //找出当前只比b[i]大一个的数 int index=-1;//默认没找到 int max=Integer.MAX_VALUE; for(int j=1;j<=n;j++){ if(j>b[i] && !used[j]){ //此时是找到了 index=j; used[j]=true; sumA+=i+1; break; } } //判断有没有找到 if(index==-1){ //此时说明没有找到,那么我们找最小的数 for(int j=1;j<=n;j++){ if(j<b[i] && !used[j]){ //此时是找到了 index=j; used[j]=true; sumB+=i+1; break; } } } //此时判断等于的情况 if(!used[b[i]] && index==-1){ //此时可以找到相同的 sumA+=0; sumB+=0; used[b[i]]=true; } } System.out.println(sumA-sumB); } }

总结

本次蓝桥杯相对前几届来说算法考的其实不多,主要还是逻辑思维问题, 我在考场上也只是做了一个填空和一个大题,大一第一次参加还是经验不够,总想着这题暴力肯定超时不愿意去写,一直坐在那里思考正解,但是这是非常不对的,我们应该先从暴力解开始优化才对,好歹写了还有一点分,再加上第一次参加肯定还是会紧张的,只能说明年继续努力吧!!!等到后面蓝桥云课加入了今年的题目,大家可以试试上述代码能通过几个案例哈(如果上述题解大佬们有更好的想法欢迎在评论区留言!!!)

Read more

【Docker进阶篇】告别OOM Kill!Java容器化内存与CPU限制实战指南

【Docker进阶篇】告别OOM Kill!Java容器化内存与CPU限制实战指南

🍃 予枫:个人主页 📚 个人专栏: 《Java 从入门到起飞》《读研码农的干货日常》 💻 Debug 这个世界,Return 更好的自己! 引言 做Java容器化部署的小伙伴,大概率都踩过这样的坑:明明给容器配置了–memory限制,JVM也设了-Xmx参数,结果应用还是频繁被OOM Kill;要么就是CPU限制设太高,资源浪费严重,设太低又导致应用卡顿。今天就彻底搞懂Java容器化中CPU和内存限制的核心逻辑,避开配置陷阱,让应用稳定运行不翻车! 文章目录 * 引言 * 一、为什么Java容器化,内存和CPU配置容易出问题? * 二、容器内存限制(--memory)配置指南(重点避坑) * 2.1 容器内存的组成的部分 * 2.2 内存配置黄金比例(实战可用) * 实战示例(重点) * 2.3 关键避坑点(必看) * 三、容器CPU限制(--cpus)

By Ne0inhk
Flutter 三方库 openapi_dart_common 的鸿蒙化适配指南 - 实现具备强类型契约的高性能 API 通讯模型、支持端侧 OpenAPI/Swagger 协议的自动化生成与对齐实战

Flutter 三方库 openapi_dart_common 的鸿蒙化适配指南 - 实现具备强类型契约的高性能 API 通讯模型、支持端侧 OpenAPI/Swagger 协议的自动化生成与对齐实战

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 openapi_dart_common 的鸿蒙化适配指南 - 实现具备强类型契约的高性能 API 通讯模型、支持端侧 OpenAPI/Swagger 协议的自动化生成与对齐实战 前言 在进行 Flutter for OpenHarmony 的企业级前后端分离开发时,如何保证客户端请求代码与后端 API 定义的绝对同步?手动编写 API 模型不仅低效,且极易引发类型不匹配导致的生产 Bug。openapi_dart_common 是 OpenAPI (Swagger) 官方生成器在 Dart 端的基石库。它提供了一套标准的序列化、参数处理及抽象拦截器机制。本文将探讨如何在鸿蒙端构建极致稳健的工程化接口层。 一、原直观解析 / 概念介绍 1.1

By Ne0inhk
Flutter 三方库 mobx_codegen — 自动化驱动的高性能响应式状态管理(适配鸿蒙 HarmonyOS Next ohos)

Flutter 三方库 mobx_codegen — 自动化驱动的高性能响应式状态管理(适配鸿蒙 HarmonyOS Next ohos)

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net。 在 Flutter 状态管理的璀璨星空中,MobX 以其“透明的函数式响应式编程”(TFRP)特性脱颖而出。它让开发者能以声明式的方式描述状态,而让框架自动处理状态变更到 UI 刷新的全过程。 在 Flutter for OpenHarmony 开发中,手动编写 MobX 繁琐的连接代码不仅效率低,且容易出错。mobx_codegen 库通过解析注解,自动生成高性能的底层观察逻辑。今天,我们将探索如何利用自动化力量,在鸿蒙平台上构建出极其灵动的响应式应用。 一、为什么需要 mobx_codegen? 1.1 MobX 的魔法核心 MobX 包含三个核心概念:Observables(被观察的状态)、Actions(改变状态的动作)和 Reactions(对新状态的自动响应)

By Ne0inhk

服务器HBA卡与RAID卡:到底有什么区别?

1.本质定义与功能定位 1.1 HBA卡(主机总线适配器) 定义:HBA(Host Bus Adapter)是连接服务器内部I/O通道与外部存储设备的硬件接口卡,主要承担协议转换和物理连接功能。 核心功能: * 提供高速数据传输通道 * 实现协议转换(如SCSI、SAS、SATA、FC等) * 将存储设备透明呈现给操作系统 * 支持直接设备访问,无中间处理层 1.2 RAID卡(磁盘阵列控制器) 定义:RAID(Redundant Array of Independent Disks)卡是专门管理多个硬盘组成磁盘阵列的硬件控制器,具备数据冗余和性能优化功能。 核心功能: * 实现RAID级别配置(RAID 0/1/5/6/10等) * 提供数据冗余保护与容错机制 * 优化磁盘读写性能(条带化、缓存等) * 支持热插拔与故障磁盘替换

By Ne0inhk