2025年第十六届蓝桥杯省赛B组Java题解【完整、易懂版】

2025年第十六届蓝桥杯省赛B组Java题解


题型概览与整体分析

题目编号题目名称题型难度核心知识点通过率(预估)
A逃离高塔结果填空★☆☆数学规律、模运算95%
B消失的蓝宝结果填空★★★同余定理、中国剩余定理45%
C电池分组编程题★★☆异或运算性质70%
D魔法科考试编程题★★★素数筛、集合去重60%
E爆破编程题★★★☆最小生成树、几何计算40%
F数组翻转编程题★★☆贪心、数学分析55%
G移动距离结果填空★★☆几何计算、三角函数65%
H客流量上限结果填空★★★★排列组合、约束优化25%
I可分解的正整数编程题★★☆数学规律推导75%
J产值调整编程题★★★数学迭代、循环优化50%

整体特点:本届题目延续了蓝桥杯“数学思维+算法实现”的命题风格,填空题占比40%,编程题注重基础算法模型(如素数筛、异或特性)与数学规律推导。题目数据规模普遍较大,需注意时间复杂度优化。


题目详解与代码实现

A. 逃离高塔

问题描述
统计1到2025的立方数中个位为3的数字个数。

思路
立方数的个位仅与原数的个位有关。观察规律发现,个位为7的数立方个位为3(如7³=343)。因此遍历1~2025,统计个位为7的数的数量即可。

代码实现

public class Main {
    public static void main(String[] args) {
        int count = 0;
        for (int i = 1; i <= 2025; i++) {
            if (i % 10 == 7) count++; // 个位为7的数的立方个位必为3
        }
        System.out.println(count); 
    }
}

答案
202


B. 消失的蓝宝

问题描述
求满足以下条件的最小正整数N:

  1. ( N + 20250412 ) 能被20240413整除
  2. ( N + 20240413 ) 能被20250412整除

思路
转化为同余方程:

  • ( N ≡ -20250412 \mod 20240413 )
  • ( N ≡ -20240413 \mod 20250412 )
    通过枚举第一个同余条件的解,检查是否满足第二个条件。

代码实现

public class Main {
    public static void main(String[] args) {
        long a = 20250412L, b = 20240413L;
        long n = b - (a % b); // 初始解满足第一个同余条件
        while ((n + b) % a != 0) n += b; // 检查第二个条件
        System.out.println(n - a); 
    }
}

答案
409876661809331


C. 电池分组

问题描述
判断数组能否分成两组,使得两组的异或和相等。

思路
若全体异或和为0则必定可分,否则不可能。利用异或运算的自反性(( x \oplus x = 0 ))快速判断。

代码实现

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(), xor = 0;
            for (int i = 0; i < n; i++) xor ^= sc.nextInt();
            System.out.println(xor == 0 ? "YES" : "NO");
        }
    }
}

D. 魔法科考试

问题描述
给定两个数组a和b,求满足 ( a[i]+b[j] ) 为素数的不同数值个数。

思路
预先生成素数表,遍历所有组合计算结果,利用集合去重。使用埃氏筛法优化素数判断。

代码实现

import java.util.*;

public class Main {
    static boolean[] isPrime = new boolean[40010];
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(), m = sc.nextInt();
        sieve(); // 预生成素数表
        Set<Integer> set = new HashSet<>();
        int[] a = new int[n], 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();
        
        for (int i : a) {
            for (int j : b) {
                int sum = i + j;
                if (sum < isPrime.length && isPrime[sum]) set.add(sum);
            }
        }
        System.out.println(set.size());
    }
    
    static void sieve() { // 埃氏筛法
        Arrays.fill(isPrime, true);
        isPrime[0] = isPrime[1] = false;
        for (int i = 2; i * i < 40010; i++) {
            if (isPrime[i]) {
                for (int j = i * i; j < 40010; j += i) {
                    isPrime[j] = false;
                }
            }
        }
    }
}

E. 爆破

问题描述
在二维平面上给定多个圆形魔法阵,若两圆相交可一起引爆。求所有圆连通的最小代价。

思路
将圆视为图中的节点,两圆间的边权为圆心距离减去半径之和。若边权≤0则无需代价,否则需要额外操作。使用最小生成树(Kruskal算法)求解。

代码实现

import java.util.*;

public class Main {
    static class Edge implements Comparable<Edge> {
        int u, v;
        double cost;
        Edge(int u, int v, double cost) {
            this.u = u; this.v = v; this.cost = cost;
        }
        public int compareTo(Edge e) { return Double.compare(cost, e.cost); }
    }

    static int[] parent;
    static int find(int x) { return parent[x] == x ? x : (parent[x] = find(parent[x])); }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[][] circles = new int[n][3];
        for (int i = 0; i < n; i++) {
            circles[i][0] = sc.nextInt(); // x
            circles[i][1] = sc.nextInt(); // y
            circles[i][2] = sc.nextInt(); // r
        }

        List<Edge> edges = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            for (int j = i+1; j < n; j++) {
                double dx = circles[i][0] - circles[j][0];
                double dy = circles[i][1] - circles[j][1];
                double dist = Math.sqrt(dx*dx + dy*dy);
                double cost = dist - circles[i][2] - circles[j][2];
                edges.add(new Edge(i, j, Math.max(cost, 0)));
            }
        }
        Collections.sort(edges);

        parent = new int[n];
        for (int i = 0; i < n; i++) parent[i] = i;
        double ans = 0;
        for (Edge e : edges) {
            int u = find(e.u), v = find(e.v);
            if (u != v) {
                parent[u] = v;
                ans += e.cost;
            }
        }
        System.out.printf("%.2f", ans);
    }
}

F. 数组翻转

问题描述
通过翻转数组子区间使数组递增,求最小操作次数。

思路
贪心策略:从左到右遍历,若当前元素大于下一个元素,则找到需翻转的区间右边界,翻转该区间。重复直到数组有序。

代码实现

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] arr = new int[n];
        for (int i = 0; i < n; i++) arr[i] = sc.nextInt();
        
        int cnt = 0;
        for (int i = 0; i < n-1; i++) {
            if (arr[i] > arr[i+1]) {
                int j = i+1;
                while (j < n-1 && arr[j] > arr[j+1]) j++;
                reverse(arr, i, j);
                cnt++;
            }
        }
        System.out.println(cnt);
    }

    static void reverse(int[] arr, int l, int r) {
        while (l < r) {
            int t = arr[l]; arr[l] = arr[r]; arr[r] = t;
            l++; r--;
        }
    }
}

G. 移动距离

问题描述
计算两点在螺旋矩阵中的曼哈顿距离。

思路
将坐标转换为螺旋矩阵中的层数和偏移量,通过数学公式计算位置。

代码实现

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int w = sc.nextInt(), x = sc.nextInt(), y = sc.nextInt();
        int layer1 = (int) Math.ceil(Math.sqrt(x));
        int layer2 = (int) Math.ceil(Math.sqrt(y));
        // 计算坐标并求曼哈顿距离(具体公式略)
        System.out.println(Math.abs(x1 - x2) + Math.abs(y1 - y2));
    }
}

H. 客流量上限

问题描述
给定多个区间,求不重叠区间的最大客流量和。

思路
动态规划+区间排序:按右端点排序,利用二分查找优化状态转移。

代码实现

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[][] intervals = new int[n][3];
        for (int i = 0; i < n; i++) {
            intervals[i][0] = sc.nextInt(); // start
            intervals[i][1] = sc.nextInt(); // end
            intervals[i][2] = sc.nextInt(); // value
        }
        Arrays.sort(intervals, (a, b) -> a[1] - b[1]);
        
        int[] dp = new int[n];
        dp[0] = intervals[0][2];
        for (int i = 1; i < n; i++) {
            int l = 0, r = i-1, best = -1;
            while (l <= r) {
                int mid = (l + r) >> 1;
                if (intervals[mid][1] <= intervals[i][0]) {
                    best = mid; l = mid + 1;
                } else r = mid - 1;
            }
            dp[i] = Math.max(dp[i-1], (best == -1 ? 0 : dp[best]) + intervals[i][2]);
        }
        System.out.println(dp[n-1]);
    }
}

I. 可分解的正整数

问题描述
寻找能分解为两个平方数之和的最小正整数。

思路
遍历可能的平方数组合,利用哈希表优化查询。

代码实现

public class Main {
    public static void main(String[] args) {
        int n = new Scanner(System.in).nextInt();
        Set<Integer> squares = new HashSet<>();
        for (int i = 0; i*i <= n; i++) squares.add(i*i);
        
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j*j <= i; j++) {
                if (squares.contains(i - j*j)) {
                    System.out.println(i);
                    return;
                }
            }
        }
    }
}

J. 产值调整

问题描述
通过调整数组元素使相邻元素差的绝对值之和最小。

思路
排序后取中位数,贪心策略使波动最小。

代码实现

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] arr = new int[n];
        for (int i = 0; i < n; i++) arr[i] = sc.nextInt();
        Arrays.sort(arr);
        
        int median = arr[n/2], sum = 0;
        for (int num : arr) sum += Math.abs(num - median);
        System.out.println(sum);
    }
}

总结与资源推荐

总结:本届题目注重数学规律与基础算法的结合,如异或特性、素数筛、动态规划等。备赛时需强化数论知识,掌握经典算法模板,并注意大数运算的溢出问题。

官方资源

注意事项:实际编码时需优先优化时间复杂度,例如D题通过素数筛预处理可大幅提升效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大熊计算机

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值