2025 年蓝桥杯 Java B 组真题解析分享

今年是我第二次参加蓝桥杯软件类Java B组的比赛,虽然赛前做了不少准备,但真正坐在考场上时,还是有种熟悉又紧张的感觉。蓝桥杯的题目一向以“基础+创新”著称,今年也不例外,每道题都考验着我们对算法的理解、代码实现能力和临场应变的综合实力。

这篇博客我想记录一下我对今年Java B组算法题的整体思路、解法细节、以及做题过程中遇到的一些坑和收获。希望对正在备赛或者想了解蓝桥杯题型的同学有帮助,也算是给自己的一个总结和回顾。

洛谷上整理有今年的Java B组原题,大家可以点击题目名称跳转到对应的链接查看原题或者进行测试。


1. 题目一:逃离立方塔

题目描述

小蓝一觉醒来,发现自己被困在一座高耸的塔中。这座塔共有 2025 2025 2025 层,每一层都刻有一个数字的立方值,从底层的 1 3 , 2 3 , 3 3 , … 1^3,2^3,3^3,\dots 13,23,33, 一直到顶层的 202 5 3 2025^3 20253,层层叠叠,直入云霄。塔顶有一扇门,门旁刻着一行字:“若想离开此塔,需找出这些立方数中个位数字为 3 3 3 的数的个数。”

小蓝非常着急,因为他需要尽快离开这座塔,去参加即将到来的蓝桥杯比赛。时间紧迫,请你帮助他解答这个问题。

输入格式

输出格式

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只需要编写一个程序输出这个整数,输出多余的内容将无法得分。


解题思路

我们只需要统计从 1 到 2025 的所有整数的立方值中,个位数字是 3 的数量。由于立方值可能超出 int 范围,需使用 long 类型来避免溢出。

此外,我们还可以通过观察立方数的个位规律进行优化。只有个位为 7 的数字,其立方的个位才为 3(因为 7 3 = 343 7^3 = 343 73=343,个位是 3),因此我们也可以仅统计个位为 7 的数字的个数(这种思路就不写代码了,实际上可以直接看出来是有202个)。

代码实现

public class Main {public static void main(String[] args) {int count = 0;for (int i = 1; i <= 2025; i++) {long cube = (long) i * i * i;if (cube % 10 == 3) {count++;}}System.out.println(count);}
}

2. 题目二:消失的蓝宝

题目描述

“蓝宝又不见了!” 2025 年 4 月 12 日,蓝桥杯吉祥物 “蓝宝” 在省赛前夕突然失踪。小蓝翻阅了蓝宝的活动记录,发现它的出现时间似乎与蓝桥杯的两个重要日期密切相关:

  • 第十六届省赛日期 20250412 20250412 20250412
  • 第十五届省赛日期 20240413 20240413 20240413

经过分析,小蓝推测蓝宝的下一次出现时间 N N N 满足以下条件:

  1. N + 20250412 N + 20250412 N+20250412 能被 20240413 20240413 20240413 整除。
  2. N + 20240413 N + 20240413 N+20240413 能被 20250412 20250412 20250412 整除。

现在,请你帮小蓝找出满足条件的最小正整数 N N N,预测蓝宝的下一次出现时间。

输入格式

输出格式

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只需要编写一个程序输出这个整数,输出多余的内容将无法得分。


解题思路

将两个条件表示为:

  • N ≡ -20250412 (mod 20240413)

  • N ≡ -20240413 (mod 20250412)

这是典型的中国剩余定理求解同余方程组问题。由于两个模数互质,可以使用暴力枚举从最小满足第一个同余的数开始,每次加上 20240413,直到也满足第二个同余条件为止。

代码实现

public class Main {public static void main(String[] args) {long a = 20250412;long b = 20240413;// 求最小满足 (N + a) % b == 0long n = b - (a % b);while ((n + b) % a != 0) {n += b;}System.out.println(n);}
}

3. 题目三:电池分组

题目描述

研究员小蓝受到实验室主任的指示,需要对实验室新研发的 N N N 个新型能量电池进行分组实验。这 N N N 个能量电池的能量值分别用 A 1 , A 2 , … , A N A_1, A_2, \dots , A_N A1,A2,,AN 表示,每个能量值都是一个整数。为了保证实验的安全性,小蓝需要将这 N N N 个能量电池分成两组,使得这两组能量电池的能量值异或和相等。

能量值的异或和计算方法如下:对于一个集合 S S S,其异或和等于集合中所有元素的按位异或结果。例如,集合 { 1 , 2 , 3 } \{1, 2, 3\} {1,2,3} 的异或和为 1 ⊕ 2 ⊕ 3 = 0 1 \oplus 2 \oplus 3 = 0 123=0,其中 ⊕ \oplus 表示异或运算。

现在,小蓝想知道,这 N N N 个能量电池能否分成两组,使得这两组能量电池的能量值异或和相等。注意,每组至少包含一个能量电池。

请你帮帮他!

输入格式

输入的第一行包含一个整数 T T T,表示测试用例的数量。

每个测试用例占两行:

  • 第一行包含一个整数 N N N,表示能量电池的数量。
  • 第二行包含 N N N 个整数 A 1 , A 2 , … , A N A_1, A_2, \dots , A_N A1,A2,,AN,表示每个能量电池的能量值。

输出格式

对于每个测试用例,输出一行。如果可以将能量电池分成两组,使得这两组能量电池的能量值异或和相等,则输出 YES;否则,输出 NO

输入输出样例 #1

输入 #1

2
3
1 2 3
4
1 2 3 4

输出 #1

YES
NO

说明/提示

评测用例规模与约定

  • 对于 30 % 30\% 30% 的评测用例, 1 ≤ T ≤ 10 1 \leq T \leq 10 1T10 2 ≤ N ≤ 100 2 \leq N \leq 100 2N100 1 ≤ A i ≤ 1 0 3 1 \leq A_i \leq 10^3 1Ai103
  • 对于 100 % 100\% 100% 的评测用例, 1 ≤ T ≤ 1 0 3 1 \leq T \leq 10^3 1T103 2 ≤ N ≤ 1 0 3 2 \leq N \leq 10^3 2N103 1 ≤ A i ≤ 1 0 5 1 \leq A_i \leq 10^5 1Ai105

异或运算特性

  1. 异或是一个非常特殊的运算,它满足以下性质:

    • 任何数和 0 异或仍为该数: x ⊕ 0 = x x \oplus 0 = x x0=x

    • 相同的两个数异或结果为 0: x ⊕ x = 0 x \oplus x = 0 xx=0

    • 异或运算是可交换的: x ⊕ y = y ⊕ x x \oplus y = y \oplus x xy=yx

    • 异或运算是结合的: ( x ⊕ y ) ⊕ z = x ⊕ ( y ⊕ z ) (x \oplus y) \oplus z = x \oplus (y \oplus z) (xy)z=x(yz)

  2. 如果将一组数分成两组,使得两组的异或和相等,实际上就是要求整个数组的异或和为 0,因为:

    • 如果整个数组的异或和是 S S S,假设可以分成两组使得两组异或和相等,则这些组的异或和都应该是 S / 2 S/2 S/2,但是如果 S S S 本身不为 0,是无法做到的。

因此,若数组的异或和是 0,则说明可以将其分成两组使得这两组的异或和相等,否则不可能。

解题思路

  • 对于每个测试用例,首先计算所有能量电池的异或和。

  • 如果异或和为 0,则输出 “YES”,表示可以分成两组;如果异或和不为 0,则输出 “NO”。

##代码实现

import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int T = sc.nextInt();  // 测试用例的数量while (T-- > 0) {int N = sc.nextInt();  // 电池的数量int xorSum = 0;  // 用来存储异或和for (int i = 0; i < N; i++) {xorSum ^= sc.nextInt();  // 计算异或和}// 如果异或和为0,则可以分成两组,否则不可以if (xorSum == 0) {System.out.println("YES");} else {System.out.println("NO");}}sc.close();}
}

4. 题目四:魔法科考试

题目描述

小明正在参加魔法科的期末考试,考生需要根据给定的口诀组合出有效的魔法。其中,老师给定了 n n n 个上半部分口诀 a 1 , a 2 , … , a n a_1, a_2, \dots , a_n a1,a2,,an m m m 个下半部分口诀 b 1 , b 2 , … , b m b_1, b_2, \dots , b_m b1,b2,,bm,均用整数表示。完整的口诀包含一个上半部分口诀和一个下半部分口诀,当选用两个口诀 a i a_i ai b j b_j bj,将组合出完整口诀 S = a i + b j S = a_i + b_j S=ai+bj

S S S 满足 S ≤ n + m S \leq n + m Sn+m S S S 为质数时,魔法是有效的。魔法的种类只和 S S S 的大小有关。如果每个上半部分口诀和每个下半部分口诀在不同的组合中可以重复使用,小明想知道一共可能组合出多少种不同的有效魔法?

输入格式

输入共三行。

  • 第一行为两个正整数 n , m n, m n,m
  • 第二行为 n n n 个由空格分开的正整数 a 1 , a 2 , … , a n a_1, a_2, \dots , a_n a1,a2,,an
  • 第三行为 m m m 个由空格分开的正整数 b 1 , b 2 , … , b m b_1, b_2, \dots , b_m b1,b2,,bm

输出格式

输出共 1 1 1 行,一个整数表示答案。

输入输出样例 #1

输入 #1

3 4
2 3 10
3 4 5 1

输出 #1

3

说明/提示

样例说明

可以组合出 3 , 5 , 7 3,5,7 3,5,7 这三个有效魔法。

评测用例规模与约定

  • 对于 20 % 20\% 20% 的评测用例, n , m ≤ 200 n, m \leq 200 n,m200
  • 对于 60 % 60\% 60% 的评测用例, n , m ≤ 2000 n, m \leq 2000 n,m2000
  • 对于 100 % 100\% 100% 的评测用例, 1 ≤ n , m ≤ 20000 1\leq n, m \leq 20000 1n,m20000 1 ≤ a i , b i ≤ 20000 1\leq a_i, b_i \leq 20000 1ai,bi20000

解题思路

我们可以通过以下步骤来解决问题:

  1. 计算可能的 S S S 值:对于每对 a i a_i ai b j b_j bj,计算出 S = a i + b j S = a_i + b_j S=ai+bj。并且我们需要检查这个 S S S 是否满足:

    • S ≤ n + m S \leq n + m Sn+m

    • S S S 是质数

  2. 使用质数筛选:由于我们需要对多个数进行质数判断,可以使用 埃拉托斯特尼筛法 来预处理所有可能的数(从 1 到 n + m n + m n+m)的质数标记。

  3. 去重:我们需要记录每个组合出的有效魔法,即每个满足条件的质数值。为了去重,可以使用集合(set)。

代码实现

import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);// 读取输入int n = sc.nextInt();int m = sc.nextInt();int[] a = new int[n];int[] b = new int[m];for (int i = 0; i < n; i++) {a[i] = sc.nextInt();}for (int i = 0; i < m; i++) {b[i] = sc.nextInt();}// 计算最大可能的 Sint maxSum = n + m;// 使用埃拉托斯特尼筛法计算质数boolean[] isPrime = new boolean[maxSum + 1];isPrime[0] = isPrime[1] = false; // 0 和 1 不是质数for (int i = 2; i <= maxSum; i++) {isPrime[i] = true;}// 筛选出质数for (int i = 2; i * i <= maxSum; i++) {if (isPrime[i]) {for (int j = i * i; j <= maxSum; j += i) {isPrime[j] = false;}}}// 使用集合去重存储有效魔法的质数Set<Integer> validPrimes = new HashSet<>();// 遍历所有组合计算 Sfor (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {int sum = a[i] + b[j];if (sum <= maxSum && isPrime[sum]) {validPrimes.add(sum);}}}// 输出有效魔法的数量System.out.println(validPrimes.size());sc.close();}
}

5. 题目五:爆破

题目描述

小明正在参加一场爆破工作。人们在地面上放置了 n n n 个爆炸魔法阵,第 i i i 个魔法阵的圆心坐标为 ( x i , y i ) (x_i, y_i) (xi,yi),半径为 r i r_i ri。如果两个魔法阵相交,则它们可以一起引爆;如果两个魔法阵不相交,则可以再使用一条魔法回路将它们的边缘连接起来。小明想知道最少需要布置总长度多长的魔法回路才能使得所有的魔法阵可以一起引爆?

输入格式

输入共 n + 1 n + 1 n+1 行。

  • 第一行为一个正整数 n n n
  • 后面 n n n 行,每行三个整数表示 x i , y i , r i x_i, y_i, r_i xi,yi,ri

输出格式

输出共 1 1 1 行,一个浮点数表示答案(四舍五入保留两位小数)。

输入输出样例 #1

输入 #1

4
0 0 1
2 0 2
-3 0 1
4 4 1

输出 #1

2.47

说明/提示

样例说明

  • 使用魔法回路连接第 1 1 1 3 3 3 个魔法阵,长度为 1 1 1
  • 使用魔法回路连接第 2 2 2 4 4 4 个魔法阵,长度为 2 5 − 3 = 1.47 2\sqrt{5} - 3 = 1.47 25 3=1.47

总长度 2.47 2.47 2.47

评测用例规模与约定

  • 对于 40 % 40\% 40% 的评测用例, n ≤ 500 n \leq 500 n500
  • 对于 100 % 100\% 100% 的评测用例, 1 ≤ n ≤ 5000 1\leq n \leq 5000 1n5000 ∣ x i ∣ , ∣ y i ∣ ≤ 2000 |x_i|, |y_i| \leq 2000 xi,yi2000 0 < r i ≤ 20 0 < r_i \leq 20 0<ri20

解题思路

魔法阵之间:

  • 若相交(圆与圆相交或相切),可以直接连通;

  • 若不相交,可以用一条魔法回路(即线段)将它们连接起来,花费等于两圆心的距离减去两个半径之和。

因此,我们可以将这些魔法阵看作图中的点,它们之间的“最短连接代价”看作边的权值,求最小总连接长度的问题就变成了**最小生成树(Minimum Spanning Tree,MST)**问题。

我们可以采用经典的 Prim 算法 来求解:

  1. 任意选择一个起点加入生成树;

  2. 每次从当前生成树中,选择一条最短的连接边将一个新节点加入;

  3. 重复该操作直到所有点都加入树中。

在计算两魔法阵间的连接长度时:

  • 如果两个魔法阵相交(两圆心距离小于等于半径之和),则不需要额外连接,代价为 0;

  • 否则,连接代价为 两圆心距离 - 两圆半径之和。

由于最多只有 5000 个魔法阵,用 Prim 算法配合数组实现可以顺利通过本题。

代码实现

import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();double[][] arr = new double[n][3]; // 存坐标和半径for (int i = 0; i < n; i++) {arr[i][0] = sc.nextDouble(); // xarr[i][1] = sc.nextDouble(); // yarr[i][2] = sc.nextDouble(); // r}boolean[] visited = new boolean[n]; // 标记已连接的魔法阵double[] minDist = new double[n];   // 每个点与当前树的最短距离for (int i = 0; i < n; i++) minDist[i] = Double.MAX_VALUE;double totalLength = 0;minDist[0] = 0; // 从第一个魔法阵开始连接for (int i = 0; i < n; i++) {// 找到当前未访问且距离最小的点int u = -1;for (int j = 0; j < n; j++) {if (!visited[j] && (u == -1 || minDist[j] < minDist[u])) {u = j;}}visited[u] = true;totalLength += minDist[u];// 更新其它点与当前树的最小距离for (int v = 0; v < n; v++) {if (!visited[v]) {double dist = getLength(arr[u][0], arr[u][1], arr[u][2],arr[v][0], arr[v][1], arr[v][2]);if (dist < minDist[v]) {minDist[v] = dist;}}}}System.out.printf("%.2f\n", totalLength);}// 计算两个魔法阵的“连接长度”(如果相交则为0)static double getLength(double x1, double y1, double r1, double x2, double y2, double r2) {double dx = x1 - x2;double dy = y1 - y2;double centerDist = Math.sqrt(dx * dx + dy * dy);double res = centerDist - (r1 + r2);return Math.max(0, res);}
}

6. 题目六:数组翻转

题目描述

小明生成了一个长度为 n n n 的正整数数组 a 1 , a 2 , … , a n a_1, a_2, \dots , a_n a1,a2,,an,他可以选择连续的一段数 a l , a l + 1 , … , a r a_l, a_{l+1}, \dots, a_r al,al+1,,ar,如果其中所有数都相等即 a l = a l + 1 = ⋯ = a r a_l = a_{l+1} = \dots = a_r al=al+1==ar,那么他可以获得 ( r − l + 1 ) × a l (r - l + 1) \times a_l (rl+1)×al 的分数。

在选择之前,为了让分数尽可能大,他决定先选择数组中的一段区间,对其进行左右翻转。他想知道在对数组进行翻转之后他能获得的最大分数是多少?

提示:当翻转 a l a_l al a r a_r ar 这段区间后,整个数组会变为:

a 1 , a 2 , … , a l − 1 , a r , a r − 1 , … , a l + 1 , a l , a r + 1 , … , a n a_1, a_2, \dots , a_{l-1}, a_r, a_{r-1}, \dots , a_{l+1}, a_l, a_{r+1}, \dots , a_n a1,a2,,al1,ar,ar1,,al+1,al,ar+1,,an

输入格式

输入共两行。

  • 第一行为一个正整数 n n n
  • 第二行为 n n n 个由空格分开的正整数 a 1 , a 2 , … , a n a_1, a_2, \dots , a_n a1,a2,,an

输出格式

输出共 1 1 1 行,一个整数表示答案。

输入输出样例 #1

输入 #1

7
4 4 3 3 2 1 3

输出 #1

9

说明/提示

样例说明

翻转区间 [ 5 , 7 ] [5, 7] [5,7],数组变为 4 , 4 , 3 , 3 , 3 , 1 , 2 4, 4, 3, 3, 3, 1, 2 4,4,3,3,3,1,2,最大分数为选择三个 3 3 3

评测用例规模与约定

  • 对于 20 % 20\% 20% 的评测用例, n ≤ 500 n \leq 500 n500
  • 对于 100 % 100\% 100% 的评测用例, 1 ≤ n ≤ 1 0 6 1\leq n \leq 10^6 1n106 1 ≤ a i ≤ 1 0 6 1\leq a_i \leq 10^6 1ai106

解题思路

所谓翻转操作其实没必要实现,只需要对每个数统计连续出现的次数,保留最大的两个结果。最后在遍历数值乘以(两次连续出现次数和),得到最大值输出即可。

  • 比如数值为 x 的最大连续段为 a,次长为 b,翻转后有可能拼接出一段长度 a + b 的连续段,得分为 x × (a + b)。

  • 枚举所有数值,统计其前两大连续段长度 a 和 b,取最大得分即可。

代码实现

import java.io.*;
import java.util.*;public class Main {public static void main(String[] args) throws FileNotFoundException {QReader in = new QReader();QWriter out = new QWriter();int n = in.nextInt();int[] arr = new int[n];int[][] tong = new int[1000001][2];for (int i = 0; i < n; i++) {arr[i] = in.nextInt();}for (int i = 0; i < n; i++) {int c = 0;c++;while (i < n - 1 && arr[i] == arr[i + 1]) {i++;c++;}if (c > tong[arr[i]][0]) {tong[arr[i]][1] = tong[arr[i]][0];tong[arr[i]][0] = c;} else if (c > tong[arr[i]][1]) {tong[arr[i]][1] = c;}}long s = 0;for (int i = 0; i < 1000001; i++) {long t = (long) i * (tong[i][1] + tong[i][0]);if (t > s) s = t;}out.println(s);out.close();}static class QReader {private BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));private StringTokenizer tokenizer = new StringTokenizer("");private String innerNextLine() {try {return reader.readLine();} catch (IOException e) {return null;}}public boolean hasNext() {while (!tokenizer.hasMoreTokens()) {String nextLine = innerNextLine();if (nextLine == null) {return false;}tokenizer = new StringTokenizer(nextLine);}return true;}public String next() {hasNext();return tokenizer.nextToken();}public int nextInt() {return Integer.parseInt(next());}public long nextLong() {return Long.parseLong(next());}}static class QWriter implements Closeable {private BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));public void print(Object object) {try {writer.write(object.toString());} catch (IOException e) {e.printStackTrace();}}public void println(Object object) {try {writer.write(object.toString());writer.write("\n");} catch (IOException e) {e.printStackTrace();}}@Overridepublic void close() {try {writer.close();} catch (IOException e) {e.printStackTrace();}}}
}

7. 题目七:2的幂

题目描述

小明很喜欢 2 2 2 的幂,所以他想对一个长度为 n n n 的正整数数组 { a 1 , a 2 , … , a n } \{a_1, a_2, \dots, a_n\} {a1,a2,,an} 进行改造。他可以进行如下操作任意多次(可以是 0 0 0 次):任选一个数 a i a_i ai 加上任意正整数,但不能使得加完之后的结果超过 1 0 5 10^5 105

在操作任意次后,小明希望所有数的乘积是 2 k 2^k 2k 的倍数。他想知道总共需要加的数的总和至少是多少?

输入格式

输入共两行。

  • 第一行为两个正整数 n , k n, k n,k
  • 第二行为 n n n 个由空格分开的正整数 a 1 , a 2 , … , a n a_1, a_2, \dots, a_n a1,a2,,an

输出格式

输出共 1 1 1 行,一个整数表示答案。如果不能满足条件,输出 − 1 -1 1

输入输出样例 #1

输入 #1

3 9
19 10 3

输出 #1

12

说明/提示

样例说明

将三个数分别加到 24 , 16 , 4 24, 16, 4 24,16,4,它们的乘积为 1536 = 2 9 × 3 1536 = 2^9 \times 3 1536=29×3,加的数的总和为 5 + 6 + 1 = 12 5 + 6 + 1 = 12 5+6+1=12

评测用例规模与约定

  • 对于 20 % 20\% 20% 的评测用例, n , k ≤ 10 n, k \leq 10 n,k10
  • 对于 100 % 100\% 100% 的评测用例, 1 ≤ n ≤ 500 1\leq n \leq 500 1n500 1 ≤ k ≤ 5000 1\leq k \leq 5000 1k5000 1 ≤ a i ≤ 100000 1\leq a_i \leq 100000 1ai100000

解题思路

这题咱暂时还不会,网上也没找到题解,对这题有兴趣的可以先关注我,等我研究研究后续再更新。

代码实现

// 待补充

8. 题目八:研发资源分配

题目描述

在蓝桥科技公司, A A A 部门和 B B B 部门正在竞争一种新型 AI 芯片的研发资源。

为了公平分配资源,公司设计了一个为期 N N N 天的分配方案:

每天早上, A A A 部门和 B B B 部门各自提交一个需求等级(从 1 1 1 N N N 的整数)。提交等级较高的部门获得当天的资源,资源份额等于当天的日期编号(第 1 1 1 天为 1 1 1 单位,第 2 2 2 天为 2 2 2 单位,依次递增)。若两部门提交的等级相同,则当天资源作废,双方均无法获得资源。

每个部门必须在 N N N 天内使用 1 1 1 N N N 的所有等级,且每个等级只能使用一次。

有趣的是, A A A 部门在 B B B 部门内部安插了一名 “间谍”,提前获知了 B B B 部门的需求等级提交顺序,记为排列 ( P 1 , P 2 , … , P N P_1, P_2, \dots , P_N P1,P2,,PN),其中 P i P_i Pi 表示 B B B 部门在第 i i i 天提交的需求等级。

现在,请你帮助 A A A 部门分析,在已知 B B B 部门需求等级顺序的情况下, A A A 部门的总资源份额减去 B B B 部门的总资源份额的差值最大可以是多少?

输入格式

第一行包含一个整数 N N N,表示分配方案的天数。

第二行包含 N N N 个整数 P 1 , P 2 , … , P N P_1, P_2, \dots , P_N P1,P2,,PN,表示 B B B 部门在第 1 1 1 天到第 N N N 天提交的需求等级。

输出格式

输出一个整数,表示 A A A 部门的总资源份额减去 B B B 部门的总资源份额的最大差值。

输入输出样例 #1

输入 #1

3
1 3 2

输出 #1

2

说明/提示

样例说明

A A A 部门可以选择排列 [ 2 , 1 , 3 ] [2, 1, 3] [2,1,3]

  • 1 1 1 天: A ( = 2 ) > B ( = 1 ) A(= 2) > B(= 1) A(=2)>B(=1) A A A 获得 1 1 1 单位资源;
  • 2 2 2 天: A ( = 1 ) < B ( = 3 ) A(= 1) < B(= 3) A(=1)<B(=3) B B B 获得 2 2 2 单位资源;
  • 3 3 3 天: A ( = 3 ) > B ( = 2 ) A(= 3) > B(= 2) A(=3)>B(=2) A A A 获得 3 3 3 单位资源。

两者的差值为 4 − 2 = 2 4 - 2 = 2 42=2

评测用例规模与约定

  • 对于 20 % 20\% 20% 的评测用例, 1 ≤ N ≤ 11 1 \leq N \leq 11 1N11 1 ≤ P i ≤ N 1 \leq P_i \leq N 1PiN P 1 , P 2 , … , P N P_1, P_2, \dots , P_N P1,P2,,PN 各不相同。
  • 对于 100 % 100\% 100% 的评测用例, 1 ≤ N ≤ 1 0 5 1 \leq N \leq 10^5 1N105 1 ≤ P i ≤ N 1 \leq P_i \leq N 1PiN P 1 , P 2 , … , P N P_1, P_2, \dots , P_N P1,P2,,PN 各不相同。

解题思路

这个题有点类似田忌赛马,但是更复杂一些,我们要做的不是单纯赢更多回合,而是赢更“值钱”的回合,或最起码让对方不得分。

  • 每一天都可以看成是一个“比赛”机会,比赛的资源份额等于当天是第几天。

  • B 部门在每一天提交了一个数字(1~N 的排列)。

  • 你可以将这些数据封装成一个结构体 node{val, pos}:

    • val 表示 B 提交的等级(1~N)

    • pos 表示第几天(资源是 pos 单位)

  • 然后我们可以 把这些结构体按照 val 从大到小排序,也就是 B 最贪的在前面。

  • 如果按照常规的田忌赛马的思路,我们可能会干脆用 1 去和 B 的最大数字对抗,让出这一天,然后保留上等马。但是如果 B 的上等马正好在最后一天,也就是说资源是最大的一天,这时如果使用下等马1,就等于把一大份资源送给了 B,这可能得不偿失。

  • 也就是说用下等马输给上等马是有用的,但要看代价是不是太大。如果代价很高(比如是第 N 天),可能就不如直接派出上等马与 B 的上等马打个平手,这样虽说我们也没分,但起码不会让 B 得太多分。

  • 正确的做法应该是排序后,模拟让前 k 个最贪的回合给对方(或者跟他打平),剩下的赢回来。

  • 在所有 k 情况下取最大值,就是最终的最优差值。

代码实现

import java.util.*;public class Main {static class Node {int val; // B 部门提交的需求等级int pos; // 第几天(资源值为 pos + 1)Node(int val, int pos) {this.val = val;this.pos = pos;}}public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();Node[] a = new Node[n];long total = (long) n * (n + 1) / 2; // 所有资源总和long sum = total;long ans = 0;for (int i = 0; i < n; i++) {int val = sc.nextInt();a[i] = new Node(val, i + 1); // pos 是第几天,从 1 开始}// 按照 val 降序(B 部门需求等级高的排在前)Arrays.sort(a, (x, y) -> y.val - x.val);for (int i = 0; i < n; i++) {sum -= a[i].pos; // 将当天资源让给 Bans = Math.max(ans, sum - a[i].pos); // 更新最大差值}System.out.println(ans);}
}

以上就是 2025 年蓝桥杯 Java B 组全部 8 道真题的整理与解析。

蓝桥杯不仅是一次算法水平的检验,更是一次思维方式和时间管理的挑战。今年的题目让我意识到基础真的非常重要,同时也要不断锻炼自己解决陌生问题的能力。

无论最终成绩如何,这次经历都让我成长了不少。也希望这篇博客能给你带来一些启发。如果你也正在准备蓝桥杯,记得多刷真题、多做总结,相信你也一定能在赛场上发挥出自己的最佳水平!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/77205.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue3服务器端渲染深度实践:架构、性能与全栈集成

一、SSR架构设计模式 1.1 架构模式选择矩阵 维度CSRSSR混合渲染首次内容渲染(FCP)慢(依赖JS执行)快(HTML直出)按路由动态选择SEO支持需预渲染原生支持关键页预渲染服务端压力低(静态托管)高(实时渲染)使用缓存中间层TTI(可交互时间)受限于JS体积需等待Hydration渐进式激活适用…

2025年泰迪杯数据挖掘竞赛B题论文首发+问题一二三四代码分享

料 基于穿戴装备的身体活动监测 摘要 随着科技的进步&#xff0c;加速度计&#xff0c;能够实时、准确地捕捉人体的动态变化&#xff0c;成为医学应用中的一个重要工具。本文将基于题目收集数据进行相关研究。 针对题目给出的数据集&#xff0c;我们首先进行数据清洗工作。首…

国内AI搜索平台与ChatGPT横向对比分析

一、核心技术差异 1、‌百度文小言‌ 基于文心大模型4.0升级&#xff0c;主打“新搜索”能力&#xff0c;支持多模态输入&#xff08;语音、图片、视频&#xff09;和富媒体搜索结果‌。 独有的“记忆个性化”功能可结合用户历史行为优化回答&#xff0c;并在医疗、教育等垂直…

安卓环境搭建开发工具下载Gradle下载

1.安装jdk(使用java语言开发安卓app) 核心库 java.lang java.util java.sq; java.io 2.安装开发工具(IDE)android studio https://r3---sn-2x3elnel.gvt1-cn.com/edgedl/android/studio/install/2023.3.1.18/android-studio-2023.3.1.18-windows.exe下载完成后一步一步安装即…

Python 趣味学习 -数据类型脱口秀速记公式 [特殊字符]

&#x1f3a4; Python数据类型脱口秀速记公式 &#x1f40d; 1️⃣ 四大金刚登场 "Set叔(无序洁癖)、Tuple爷(顽固老头)、List姐(百变女王)、Dict哥(万能钥匙)"2️⃣ 特性对比RAP &#x1f3b6; 内存/作用域&#xff1a; 全局变量 → 函数内修改 → 可变(mutable)会…

单片机 | 基于51单片机的倾角测量系统设计

以下是一个基于51单片机的倾角测量系统设计详解,包含原理、公式和完整代码: 一、系统原理 核心器件:MPU6050(集成3轴加速度计+陀螺仪) 主控芯片:STC89C52RC(51单片机) 显示模块:LCD1602液晶 工作原理: 通过MPU6050采集XYZ三轴加速度数据,利用重力加速度分量计算俯仰…

2025年4月16日华为留学生笔试第二题200分

📌 点击直达笔试专栏 👉《大厂笔试突围》 💻 春秋招笔试突围在线OJ 👉 笔试突围OJ 02. 图书馆借阅管理系统 问题描述 卢小姐是一家大学图书馆的管理员,她需要开发一个简单的图书借阅管理系统来处理日常的图书流通操作。系统需要支持以下四种操作: in s:表示一本…

Linux通用一键换源脚本.sh - ubuntu、centos全自动更换国内源 - LinuxMirrors神器

效果 脚本 bash <(curl -sSL https://linuxmirrors.cn/main.sh) 来自 https://linuxmirrors.cn/ 截图 ending...

【Unity】JSON数据的存取

这段代码的结构是为了实现 数据的封装和管理&#xff0c;特别是在 Unity 中保存和加载玩家数据时。以下是对代码设计的逐步解释&#xff1a; 1. PlayerCoin 类 PlayerCoin 是一个简单的数据类&#xff0c;用于表示单个玩家的硬币信息。它包含以下字段&#xff1a; count&…

python实现音视频下载器

一、环境准备 确保当前系统已安装了wxPython 、 yt-dlp 和FFmpeg。当前主要支持下载youtube音视频 1、安装wxPython pip install wxPython2、安装yt-dp pip install wxPython yt-dlp3、安装FFmpeg 在Windows 10上通过命令行安装FFmpeg&#xff0c;最简便的方式是使用包管理…

使用 vxe-table 来格式化任意的金额格式,支持导出与复制单元格格式到 excel

使用 vxe-table 来格式化任意的金额格式&#xff0c;支持导出与复制单元格格式到 excel 查看官网&#xff1a;https://vxetable.cn gitbub&#xff1a;https://github.com/x-extends/vxe-table gitee&#xff1a;https://gitee.com/x-extends/vxe-table 安装 npm install vx…

知识图谱 数据准备

任何类型的数据格式都可以用于构建知识图谱&#xff0c;只要能够从中提取出实体&#xff08;Entities&#xff09;、关系&#xff08;Relationships&#xff09;和属性&#xff08;Attributes&#xff09;。但实际操作中&#xff0c;不同数据格式的处理难度、工具支持和效率差异…

Docker 设置镜像源后仍无法拉取镜像问题排查

#记录工作 Windows系统 在使用 Docker 的过程中&#xff0c;许多用户会碰到设置了国内镜像源后&#xff0c;依旧无法拉取镜像的情况。接下来&#xff0c;记录了操作要点以及问题排查方法&#xff0c;帮助我们顺利解决这类问题。 Microsoft Windows [Version 10.0.27823.1000…

如何对Flutter应用程序进行单元测试

Flutter单元测试完全指南&#xff1a;从基础到高级实践 面试求职资源 面试试题小程序&#xff1a;涵盖测试基础、Linux操作系统、MySQL数据库、Web功能测试、接口测试、APPium移动端测试、Python知识、Selenium自动化测试相关、性能测试、计算机网络知识、Jmeter、HR面试等内…

go中我遇到的问题总结

go问题总结 1 - go中的nil等于java中的null吗 在 Go 和 Java 中,nil 和 null 都用于表示“空值”,但它们的实现和使用方式有所不同。 以下是 Go 中的 nil 和 Java 中的 null 之间的对比: 1. Go 中的 nil 在 Go 中,nil 是一个预定义的常量,表示零值。它的行为根据数据类…

【android telecom 框架分析 01】【基本介绍 2】【BluetoothPhoneService为何没有源码实现】

1. 背景 我们会在很多资料上看到 BluetoothPhoneService 类&#xff0c;但是我们在实际 aosp 中确找不到具体的实现&#xff0c; 这是为何&#xff1f; 这是一个很好的问题&#xff01;虽然在车载蓝牙电话场景中我们经常提到类似 BluetoothPhoneService 的概念&#xff0c;但…

微机控制电液伺服汽车减震器动态试验系统

微机控制电液伺服汽车减震器动态试验系统&#xff0c;用于对汽车筒式减震器、减震器台架、驾驶室减震装置、发动机悬置软垫总成、发动机前置楔形支撑总成等的示功图试验、速度特性试验。 主要的技术参数&#xff1a; 1、最大试验力&#xff1a;5kN&#xff1b; 2、试验力测量精…

STM32+dht11+rc522+jq8400的简单使用

1.dht11的使用 硬件&#xff1a;3v3&#xff0c;gnd&#xff0c;data数据线接一个gpio&#xff0c;三根线即可 软件&#xff1a; ①dht11.c #include "dht11.h" #include "delay.h" #include "stdbool.h"static STRUCT_DHT11_TYPEDEF dht11;…

AOSP的Doze模式-DeepIdle 初识

前言 从Android 6.0开始&#xff0c;谷歌引入了Doze模式(打盹模式)的省电技术延长电池使用时间。如果用户长时间未使用设备&#xff0c;低电耗模式会延迟应用后台 CPU 和网络活动&#xff0c;从而延长电池续航时间。根据第三方测试显示&#xff0c;两台同样的Nexus 5&#xff…

用Python Pandas高效操作数据库:从查询到写入的完整指南

一、环境准备与数据库连接 1.1 安装依赖库 pip install pandas sqlalchemy psycopg2 # PostgreSQL # 或 pip install pandas sqlalchemy pymysql # MySQL # 或 pip install pandas sqlalchemy # SQLite 1.2 创建数据库引擎 通过SQLAlchemy创建统一接口&#xff1a…