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

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

#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;
}


4 回复 0 转发 0 喜欢 13 阅读
回复 (4)
默认 最新
露米 1 天前
在看你代码的时候,我发现最外层的那个 for 循环好像漏掉了一个结束的大括号 } 呢。

这种小地方在专注逻辑时确实很容易被忽略,你可以检查一下代码末尾,补上它之后编译应该就没问题了。

如果补上之后运行还有什么疑问,或者想试着把那个 while 循环优化一下,随时欢迎回来和我交流,我会一直在这里陪着你的 🙂
另外,如果你在尝试优化 while 循环时想到了什么新点子,比如尝试用二分查找来代替逐个累加,也欢迎随时分享出来。这种不断迭代代码、追求更优解的过程,本身就是一种很大的进步呢。

这些细节的打磨可能会花一点时间,但没关系,我们可以慢慢来。期待看到你更完善的版本呀 🙂
0
露米 2026/3/18
在看你代码的时候,我发现了一个很细微的地方,想和你分享一下:🙂

while 循环里,a[i] + ans 会随着循环不断增加。如果某个同学需要增加的分数比较多,这个值可能会超过我们定义的数组大小 N。为了让代码更稳健,可以考虑给它加一个范围限制,或者把数组边界稍微再调大一点点,这样就能避免潜在的越界问题啦。

这种边界处理的小细节,往往是编程题里最容易“藏雷”
的地方,你现在已经能捕捉到具体的逻辑细节,真的很棒。如果再把这些边界风险考虑进去,代码就会变得更加稳健可靠啦。

如果你在调整过程中遇到了新的困惑,或者对题目还有其他想法,欢迎随时留言,我会一直在这里陪你讨论的 🙂
0
露米 2026/3/10
看到你在 c = sum[a[i] + ans - 1] - 1 这里特意减去了 1,这个细节捕捉得非常敏锐呢,考虑到自己提分后就不再属于“比自己分数低”的那部分人了。🙂

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

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

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

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

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

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