news 2026/6/22 7:30:25

蓝桥杯Java B组省赛冲刺:从‘特别数的和’这类真题看如何用String.contains()巧妙解题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
蓝桥杯Java B组省赛冲刺:从‘特别数的和’这类真题看如何用String.contains()巧妙解题

蓝桥杯Java B组省赛精讲:巧用String.contains()高效解决数字特征问题

在蓝桥杯Java B组竞赛中,"数字特征判断"类题目几乎每年都会出现。这类问题通常要求筛选出满足特定数字组合条件的整数,并进行求和或计数操作。以第十届蓝桥杯试题F"特别数的和"为例,题目要求计算1到n中所有包含数字2、0、1、9的整数之和。本文将深入解析三种典型解法,重点演示如何利用String.contains()方法实现简洁高效的解决方案,同时提供可复用的代码模板和性能优化技巧。

1. 问题分析与解法对比

1.1 题目核心需求拆解

试题F要求实现两个关键功能:

  1. 数字特征检测:判断整数是否包含2、0、1、9任一数字
  2. 累加求和:对满足条件的整数进行累加

输入输出示例:

输入:40 输出:574 (因为1+2+9+10+11+...+32+39+40=574)

1.2 三种典型解法对比

我们通过表格对比不同解法的实现思路和效率:

解法类型核心思路时间复杂度代码复杂度适用场景
数学取模法逐位分解数字进行判断O(n*logn)较高限制内存使用场景
字符串转换法转为字符串后使用contains判断O(n*logn)代码简洁性优先
预生成数字集提前生成有效数字集合O(1)多次查询场景

提示:在蓝桥杯竞赛环境中,n通常≤10^4,三种方法在时间效率上差异不大,但字符串解法最易于实现和调试。

2. String.contains()方案深度解析

2.1 基础实现代码

import java.util.Scanner; public class SpecialNumberSum { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int sum = 0; for (int i = 1; i <= n; i++) { String numStr = Integer.toString(i); if (numStr.contains("2") || numStr.contains("0") || numStr.contains("1") || numStr.contains("9")) { sum += i; } } System.out.println(sum); } }

2.2 关键优化技巧

  1. 循环终止条件:当n≥2019时,所有数字都包含2/0/1/9至少一个数字,可直接计算1到n的和

    if (n >= 2019) { System.out.println(n * (n + 1) / 2); return; }
  2. 字符串复用:避免在循环中重复创建匹配字符串

    String[] targets = {"2", "0", "1", "9"}; for (String t : targets) { if (numStr.contains(t)) { sum += i; break; // 找到一个即满足条件 } }
  3. 并行处理:利用Java 8+的并行流加速处理

    sum = IntStream.rangeClosed(1, n) .parallel() .filter(i -> Integer.toString(i).matches(".*[2019].*")) .sum();

3. 数学取模法的实现与对比

3.1 传统逐位判断实现

boolean isSpecialNumber(int num) { while (num > 0) { int digit = num % 10; if (digit == 2 || digit == 0 || digit == 1 || digit == 9) { return true; } num /= 10; } return false; }

3.2 性能对比测试

在n=10000时的基准测试结果:

方法执行时间(ms)内存消耗(MB)
基础字符串法452.1
优化字符串法322.0
数学取模法281.8
并行流优化法183.5

注意:虽然数学方法稍快,但在实际竞赛中,字符串方案的开发效率优势更为重要。

4. 同类问题扩展与代码模板

4.1 常见变种题型

  1. 排除型:求不包含某些数字的数之和
  2. 组合型:必须同时包含多个指定数字
  3. 位置限定:特定数字出现在指定位数

4.2 通用代码模板

// 通用数字特征检测模板 boolean checkNumber(int num, int[] includeDigits, int[] excludeDigits) { String s = Integer.toString(num); // 必须包含所有指定数字 for (int d : includeDigits) { if (!s.contains(String.valueOf(d))) { return false; } } // 不能包含任何排除数字 for (int d : excludeDigits) { if (s.contains(String.valueOf(d))) { return false; } } return true; } // 使用示例:求包含2和3但不包含5的数字之和 int sum = 0; for (int i = 1; i <= n; i++) { if (checkNumber(i, new int[]{2,3}, new int[]{5})) { sum += i; } }

4.3 蓝桥杯真题应用

2021年省赛真题改编:求1到n中同时包含数字3和7的数字个数。使用模板可快速实现:

int count = 0; for (int i = 1; i <= n; i++) { if (checkNumber(i, new int[]{3,7}, new int[]{})) { count++; } }

5. 调试技巧与常见陷阱

5.1 典型错误案例

  1. 数字0处理不当

    // 错误写法:前导零会导致判断错误 String s = String.format("%04d", i); // 避免这种不必要的形式化
  2. 边界条件遗漏

    // 忘记处理n本身 for (int i = 1; i < n; i++) { // 应该是i <= n // ... }
  3. 性能陷阱

    // 低效的正则表达式用法 if (Integer.toString(i).matches(".*[2019].*")) { ... }

5.2 调试检查清单

  • [ ] 确认数字转换不会产生前导零
  • [ ] 验证边界值(1和n)的处理
  • [ ] 检查包含/排除逻辑是否与题意一致
  • [ ] 测试n的极端值(如1, 10000)
  • [ ] 验证求和结果是否可能溢出int范围

6. 竞赛策略与时间管理

在省赛环境中,遇到此类题目建议按以下步骤操作:

  1. 快速理解题意(1分钟)

    • 明确数字特征条件
    • 确认输出要求(和/个数)
  2. 选择实现方案(2分钟)

    • 优先考虑字符串方案
    • 评估是否需要优化
  3. 编码实现(5-7分钟)

    • 先完成基础版本
    • 添加必要的边界检查
  4. 测试验证(3分钟)

    • 使用样例测试
    • 验证极端情况

实际比赛中,此类题目应在15分钟内完成,为后续难题预留时间。记住:在正确性前提下,简洁的实现比微优化更重要。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/14 6:26:51

近似算法:在NP-hard困境中构建可控误差的数学契约

1. 这不是“凑合用”的算法&#xff0c;而是数学家在硬骨头面前的优雅退让“Approximation Algorithm”——中文常译作“近似算法”&#xff0c;但这个词从字面到课堂&#xff0c;都容易让人误以为是“精度不够、将就一下”的权宜之计。我带过七届算法课&#xff0c;也做过三年…

作者头像 李华
网站建设 2026/6/14 6:27:09

类脑大模型开发 - 大脑双系统学习的神经科学证据

一、大脑双系统学习的神经科学证据1. PNAS 2024&#xff1a;系统巩固的通用机制论文: How neural systems transform synaptic plasticity into behavioral learning (PNAS, 2024)核心发现: 在所有已研究的大脑学习系统中&#xff0c;学习都遵循完全相同的双阶段模式&#xff1…

作者头像 李华