NOIP 提高组初赛 · NOIP 2011 提高组初赛试题 第 23 题

选择题 · 答案 3 · 考点:基础算法、二分查找

← 整套速查表 NOIP 提高组初赛 全部真题

题目

#include<iostream>
#include<cstring>
using namespace std;
const int SIZE = 100;
int main()
{
    int n,i,sum,x,a[SIZE];
    
    cin>>n;
    memset(a,0,sizeof(a));
    
    for(i=1;i<=n;i++){
        cin>>x;
        a[x]++;
    }
    i=0;
    sum=0;
    while(sum<(n/2+1)){
        i++;
        sum+=a[i];
    }
    cout<<i<<endl;
    return 0;
}

输入: 11 4 5 6 6 4 3 3 2 3 2 1 输出:___________

答案:3

考点

基础算法二分查找 讲解 →二分查找 真题汇总 →

解题思维

这题考的是用数组计数排序的思想找中位数。拿到题别急着跑代码,先看数据范围:输入是 1 到 n 的数,所以用下标当数值存频次;后面那个 while 循环就是不断累加频次,直到总数超过 n/2+1,那个下标 i 就是答案,相当于在有序数组里找第 n/2+1 个位置。

常见错误

最容易错的地方是以为循环里 i 是从 1 开始的,其实代码里 i 初始为 0,第一次就加了 a[0](频次为 0),这不影响结果但会让学生误判。另一个坑是算 n/2+1 时手误,n=11 时 n/2+1=6,不是 5 或 7。还有学生可能把 a[x]++ 理解成求和,其实只是统计每个数出现了几次。最后输出的是 i 而不是 a[i],别把下标和值搞混了。

详细解析(节选)

考点与命题视角

这道题属于"程序阅读"类填空题,核心考查两个知识点:一是数组计数(下标即数值),二是通过累加频次找中位数。命题人喜欢在看似复杂的循环里藏简单的逻辑,让学生误以为要模拟排序或二分,其实只要读懂"a[x]++"和"sum+=a[i]"就能秒杀。

概念人话版

1. 计数数组:题目里 a[SIZE] 的大小是 100,但输入只给到 n=11,且每个数都在 1~11 之间。a[x]++ 的意思是:读到一个数 x,就把 a[x] 这个格子加 1。相当于用数组的下标直接存数字,用格子里的值存这个数字出现了多少次。 2. 中位数的下标定义:对于 n 个数,从小到大排好序后,第 n/2+1 个数就是"下中位数"(n=11 时是第 6 个)。程序里 sum 从 0 开始,每次加 a[i],其实就是把频次从小到大累加,当 sum 第一次超过 n/2+1 时,当前的 i 就是那个数字。

逐行推演(结合输入数据)

输入:

11
4 5 6 6 4 3 3 2 3 2 1

1. cin>>n; → n=11 2. memset(a,0,sizeof(a)); → 全清零,准备计数 3. 循环 for(i=1;i<=n;i++) cin>>x; a[x]++; 统计频次: - 1 出现 1 次 → a[1]=1 - 2 出现 2 次 → a[2]=2 - 3 出现 3 次 → a[3]=3 - 4 出现 2 次 → a[4]=2 - 5 出现 1 次 → a[5]=1 - 6 出现 2 次 → a[6]=2 - 其他 a[7..11] 都是 0 4. 重置 i=0; sum=0; 5. while(sum<(n/2+1)) → n/2+1 = 6,所以条件是 sum<6 - 第 1 轮:i=0, sum+=a[0]=0 → sum=0 < 6,继续 - 第 2 轮:i=1, sum+=a[1]=1 → sum=1 < 6,继续 - 第 3 轮:i=2, sum+=a[2]=2 → sum=3 < 6,继续 - 第 4 轮:i=3, sum+=a[3]=3 → sum=6,此时 sum 不再小于 6,循环结束 6. 输出 i → 3

为什么答案是 3?

把频次按数值从小到大排:

累计:1+2+3 = 6,刚好达到第 6 个位置,对应的数值就是 3。所以程序输出 3 完全正确。

易错点再强调

考频与趋势

预测

从数据看,"基础算法"类题目在 2024-2025 年保持稳定(每年 2 题),"二分查找"类题目在 2024-2026 年爆发式增长(2024 年 9 题、2025 年 7 题、2026 年 5 题),尤其是 GESP 五级在二分查找上占比极高(16 题)。这说明命题人越来越喜欢用"计数 + 累加"这种轻量级技巧来考察二分思想,而不是直接考经典二分。因此,未来 1-2 年,这类"用数组计数找第 k 小"的程序阅读题大概率还会出现在 NOIP 提高组初赛和 CSP 提高级中,但难度不会超过本题——核心还是读懂下标即数值、累加频次到目标位置。

暂无足够依据预测具体的年份和题号,但可以确定的是:只要看到"统计频次 + 累加直到某个阈值",就要立刻想到"找第 k 小",答案往往是那个阈值对应的下标。

同考点真题

在 OI伴学 里做这道题
登录后可计时作答、查看完整六段式解析,并按你的错题自动生成同类练习。
去刷题先做一次 AI 学情诊断