1. 题目背景与需求解析
PAT(Programming Ability Test)乙级1038题是一道经典的算法练习题,主要考察对统计数据的处理能力。题目通常会给出N个学生的成绩,要求统计某个特定分数段的学生人数。这类问题在实际开发中非常常见,比如电商平台的销量统计、教育系统的成绩分析等场景。
从工程角度看,这道题的核心需求可以拆解为:
- 高效存储大量数值数据(学生成绩)
- 快速查询指定数值的出现次数
- 处理可能的大数据量情况(N可达10^6级别)
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 算法选择与优化思路
2.1 暴力解法及其局限
最直观的做法是使用数组存储所有成绩,对于每个查询都遍历整个数组计数:
c复制int scores[1000000];
// 输入部分省略
for(int i=0; i<k; i++){
int query, count=0;
scanf("%d", &query);
for(int j=0; j<n; j++){
if(scores[j] == query) count++;
}
printf("%d", count);
}
这种解法的时间复杂度是O(k*n),当n和k都很大时(比如都是10^5),总操作次数会达到10^10量级,在OJ系统中必然超时。
2.2 哈希表法的优势
更优的方案是使用哈希表(或称为计数数组)预处理:
- 创建一个大小的101的数组count(成绩范围0-100)
- 输入时直接统计每个成绩出现的次数
- 查询时直接返回count[query]的值
c复制int count[101] = {0};
// 输入时统计
for(int i=0; i<n; i++){
int score;
scanf("%d", &score);
count[score]++;
}
// 查询时直接获取
for(int i=0; i<k; i++){
int query;
scanf("%d", &query);
printf("%d", count[query]);
}
这种方法将时间复杂度降为O(n+k),空间复杂度仅为O(1)(固定大小的数组),完美满足题目要求。
