返回题解分享
讨论 / 题解分享/ 帖子详情

最少刷题数(编程题) - 题解

#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 10;

int main() {
    int n;
    cin >> n;
    int a[N]={0};
	int sum[N] = {0};
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        sum[a[i]]++;
    }
    for (int i = 1; i < N; i++) {
        sum[i] += sum[i - 1];
    }
    for (int i = 1; i <= n; i++) {
        int b = sum[N - 1] - sum[a[i]];
        int c= sum[a[i]-1];
        int ans = 0;
        while (b > c) {
                ans++;
                b=sum[N-1]-sum[a[i]+ans];
                c=sum[a[i] + ans-1]-1;
            }
        cout << ans;
        if (i < n) {
            cout << " ";
        }
}
    return 0;
}


2 回复 0 转发 0 喜欢 8 阅读
回复 (2)
默认 最新
露米 6 天前
看到你在 c = sum[a[i] + ans - 1] - 1 这里特意减去了 1,这个细节捕捉得非常敏锐呢,考虑到自己提分后就不再属于“比自己分数低”的那部分人了。🙂

用前缀和来处理这类计数问题确实非常高效,代码的整体逻辑也很清晰。如果之后在练习中遇到数据规模更大的情况,可以试着观察一下这个 while 循环的过程,看看能不能通过简单的分类讨论或者更快的查找方式来进一步提升效率。

已经做得很不错了,这种细致的解题思路对学习算法很有帮助。慢慢来,加油呀~
另外还有一个小细节,把较大的数组定义在 main 函数外面(作为全局变量)通常会更稳妥,能有效避免在某些环境下出现栈溢出的情况。

如果你在尝试优化 while 循环时有了新的想法,或者对这类题目还有其他好奇的地方,随时欢迎留言,我们一起讨论呀 🙂
0
露米 2026/2/10
看到你分享的题解啦,前缀和的思路用得很清晰呢 🙂

通过 sum 数组来预处理每个分数段的人数分布,在处理这类“统计比自己多/少的人数”的问题时确实非常高效。

我注意到在计算每个人的 ans 时,你使用了一个 while 循环来逐步寻找满足条件的最小值。目前的逻辑已经能很好地解决问题了,不过如果想挑战一下更优的效率,可以试着思考一下:基于已经算好的前缀和数组,是否可以通过分类讨论或者二分的方法,直接锁定那个“临界点”呢?

感谢分享你的思路,代码的结构很整洁,对正在学习前缀和的小伙伴很有参考价值~加油!
0