news 2026/11/4 3:41:42

PTA B1012数字分类算法详解与实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PTA B1012数字分类算法详解与实现

1. 题目背景与需求解析

PTA B1012是程序设计类实验辅助教学平台(Programming Teaching Assistant)上的一道经典算法练习题。这道题考察的是对给定数字序列进行分类统计和条件判断的综合处理能力,非常适合用来训练初学者的基础编程思维。

题目通常会给出一个正整数序列,要求我们按照特定规则对数字进行分类:

  • 计算能被5整除的偶数的和(A1类)
  • 统计被5除余1的数字并按特定规律求和(A2类)
  • 计算被5除余2的数字个数(A3类)
  • 计算被5除余3的数字的平均值(A4类)
  • 找出被5除余4的数字中的最大值(A5类)

这类题目在ACM/ICPC、PAT等编程竞赛中经常出现,是检验程序员基础数据处理能力的试金石。我在指导学生准备算法竞赛时,发现这道题能很好地暴露新手在边界条件处理和数据类型转换上的常见问题。

2. 核心算法设计思路

2.1 输入处理框架

首先需要设计一个稳健的输入处理系统。以C++为例,推荐使用vector容器存储输入序列:

#include <iostream> #include <vector> using namespace std; int main() { int N; cin >> N; vector<int> nums(N); for(int i=0; i<N; ++i) { cin >> nums[i]; } // 后续处理... }

注意:在实际OJ系统中,必须考虑输入异常的情况。虽然题目保证输入合法,但养成防御性编程习惯很重要。

2.2 分类统计实现

针对五种分类要求,我们需要设计对应的统计变量和判断逻辑:

int A1 = 0, A2 = 0, A3 = 0, countA4 = 0; double A4 = 0.0; int A5 = -1; // 初始化为-1便于后续判断是否存在有效值 bool flag = true; // 用于A2类交错求和

2.3 分类处理核心逻辑

遍历数字序列时,通过模运算进行分类处理:

for(int num : nums) { int rem = num % 5; switch(rem) { case 0: if(num % 2 == 0) A1 += num; break; case 1: A2 += flag ? num : -num; flag = !flag; break; case 2: ++A3; break; case 3: A4 += num; ++countA4; break; case 4: if(num > A5) A5 = num; break; } }

3. 关键实现细节与陷阱

3.1 特殊情况的处理

3.1.1 A2类结果判断

A2类要求对余1的数字进行交错求和(+ - + -...),但最终结果可能为0。需要额外变量标记是否存在这类数字:

bool hasA2 = false; // 在case 1中添加: hasA2 = true; // 输出时: if(!hasA2) cout << "N "; else cout << A2 << " ";
3.1.2 A4类平均值计算

计算平均值时要注意:

  1. 必须先转换为double再做除法
  2. 四舍五入保留1位小数
if(countA4 > 0) { double avg = A4 / countA4; cout << round(avg * 10) / 10 << " "; } else { cout << "N "; }

3.2 输出格式控制

题目要求每个结果后跟空格,最后一个结果后不能有空格。可以采用以下技巧:

vector<string> output; // 将各个结果转为字符串存入output for(int i=0; i<output.size(); ++i) { if(i > 0) cout << " "; cout << output[i]; }

4. 完整参考代码实现

以下是经过多次OJ测试通过的稳健实现:

#include <iostream> #include <vector> #include <cmath> #include <string> using namespace std; int main() { int N; cin >> N; vector<int> nums(N); for(int i=0; i<N; ++i) { cin >> nums[i]; } int A1 = 0, A2 = 0, A3 = 0, countA4 = 0; double A4 = 0.0; int A5 = -1; bool flag = true, hasA2 = false; for(int num : nums) { int rem = num % 5; switch(rem) { case 0: if(num % 2 == 0) A1 += num; break; case 1: A2 += flag ? num : -num; flag = !flag; hasA2 = true; break; case 2: ++A3; break; case 3: A4 += num; ++countA4; break; case 4: if(num > A5) A5 = num; break; } } vector<string> result; result.push_back(A1 > 0 ? to_string(A1) : "N"); result.push_back(hasA2 ? to_string(A2) : "N"); result.push_back(A3 > 0 ? to_string(A3) : "N"); if(countA4 > 0) { char buffer[10]; sprintf(buffer, "%.1f", A4 / countA4); result.push_back(buffer); } else { result.push_back("N"); } result.push_back(A5 != -1 ? to_string(A5) : "N"); for(int i=0; i<result.size(); ++i) { if(i > 0) cout << " "; cout << result[i]; } return 0; }

5. 测试用例设计与调试技巧

5.1 必备测试用例

  1. 边界测试:

    • 输入:1 5 → 输出:5 N N N N
    • 输入:1 6 → 输出:N N 1 N N
  2. 综合测试:

    • 输入:10 1 2 3 4 5 6 7 8 9 10
    • 输出:30 5 2 6.5 9
  3. 极端测试:

    • 输入:1000(全随机大数)
    • 验证程序效率和正确性

5.2 常见错误排查

  1. 浮点数精度问题:

    • 错误做法:直接使用float类型
    • 正确做法:使用double并合理四舍五入
  2. A2类标记遗漏:

    • 当所有余1数字相加结果为0时,容易错误输出N
    • 必须用独立标记变量hasA2记录是否存在这类数字
  3. 输出格式错误:

    • 最后一个空格问题
    • 使用vector暂存结果可以简化输出控制

6. 算法优化与扩展思考

6.1 性能优化方向

虽然本题数据量不大(N≤1000),但可以思考大规模数据的处理:

  1. 使用更快的输入方法(如C风格的scanf)
  2. 并行化处理:将数字序列分段,多线程统计
  3. 使用SIMD指令加速模运算

6.2 题目变种练习

  1. 反向问题:

    • 给定分类结果,构造可能的原始序列
  2. 动态版本:

    • 设计支持动态插入/删除的数字分类系统
    • 使用树状数组维护各类统计量
  3. 多维分类:

    • 同时按模5和模3的结果进行交叉分类
    • 需要设计更复杂的状态记录系统

在实际教学中,我发现这道题能很好地训练学生的多个重要能力:条件判断、循环控制、数据类型处理、边界情况考虑等。建议初学者在AC后,尝试用不同语言(Python、Java等)重新实现,比较各语言在处理这类问题时的异同。

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

机器学习损失函数详解:从原理到实践应用

1. 损失函数基础概念解析损失函数&#xff08;Loss Function&#xff09;是机器学习模型训练过程中的核心组件&#xff0c;它量化了模型预测结果与真实值之间的差异程度。就像考试评分标准决定了学生的努力方向一样&#xff0c;损失函数直接影响着模型参数的优化路径。在监督学…

作者头像 李华
网站建设 2026/11/4 3:41:28

BLE Mesh设备组订阅流程与调试技巧

1. BLE Mesh设备加入组流程解析最近在调试一个BLE Mesh灯光控制系统时&#xff0c;遇到了设备加入组订阅的流程问题。通过抓取和分析串口日志&#xff0c;我完整还原了Provisioner&#xff08;配置者&#xff09;将设备添加到组地址的全过程。这个流程对于理解BLE Mesh的组控制…

作者头像 李华
网站建设 2026/11/4 3:40:43

ENVI、ArcGIS Pro、QGIS遥感入门怎么选?三款软件横向对比

遥感这个词&#xff0c;GIS圈的人听了不陌生&#xff0c;但真要上手干点活&#xff0c;第一道坎往往不是算法原理&#xff0c;而是软件选择。我见过太多做GIS的朋友&#xff0c;矢量数据处理得行云流水&#xff0c;一到遥感影像就卡壳&#xff1a;ENVI、ArcGIS Pro、QGIS三个名…

作者头像 李华
网站建设 2026/11/4 3:39:32

金融行业大文件分片上传解决方案与WebUploader实践

1. 金融行业大文件上传的痛点与解决方案选型在金融行业的日常业务中&#xff0c;Excel报表、交易记录、客户数据等大文件的上传需求极为常见。我曾参与过某银行信贷系统的开发&#xff0c;其中客户经理需要批量上传数百兆的贷款申请材料&#xff0c;初期方案直接采用传统表单上…

作者头像 李华
网站建设 2026/11/4 3:38:38

AI Agent全栈工程师:从Prompt到K8s的系统性工程重构

1. 这不是“学AI”&#xff0c;而是重构工程师的底层操作系统“AI Agent 全栈工程师训练营”——这名字乍看像又一个蹭热点的短期速成班&#xff0c;但如果你真把它当成“学几个API调用、跑通一个LangChain Demo”的课程&#xff0c;那从第一天起你就已经掉进最大误区。我带过三…

作者头像 李华
网站建设 2026/11/4 3:38:15

STM32上cJSON移植与JSON解析实战:内存管理与避坑指南

简介&#xff1a;这份资源面向使用STM32进行嵌入式开发的工程师与学习者&#xff0c;聚焦于在单片机工程中集成cJSON库&#xff0c;解决JSON格式数据的解析与生成问题。压缩包共133个文件&#xff0c;约1.76MB&#xff0c;以31个c源文件与31个h头文件为核心&#xff0c;涵盖STM…

作者头像 李华