You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Codechef BUYING2代码报错,求遗漏测试用例及初学者优化建议

嘿,我来帮你排查这个问题!首先咱们先理清你的代码里的逻辑错误,以及遗漏的测试用例,再给你一些适合初学者的优化建议。

一、遗漏的测试用例与逻辑错误分析

首先,你的代码核心逻辑存在对题目的误解,这是导致答案错误的主要原因。先明确BUYING2问题的核心要求:

Chef可以选择买所有糖果袋,或者买所有袋子除了一个。要求买的袋子的总糖果数必须是X的倍数,且这个总数尽可能大。如果没有这样的正总数(即所有可能的购买组合的总和都不是X的倍数),输出-1。

你的当前逻辑是:计算所有袋子的总和sum1,取sum1//X作为s,余数r=sum1%X,然后判断r是否小于等于最小的袋子a[0]——如果是就输出s,否则输出-1。这个逻辑完全不符合题目要求,因为只有当sum1 - a[i]能被X整除时,去掉a[i]才是有效的,而不是r<=a[i]。

以下是你代码无法正确处理的典型测试用例:

  • 测试用例1:余数r存在对应a[i]满足a[i] ≡ r mod X,但a[i] > r
    输入:

    1
    3 7
    9 3 4
    

    总和sum1=16,r=16%7=2。你的代码会因为r=2<=最小袋子3,输出16//7=2,但实际情况是:

    • 买所有袋子总和16,不是7的倍数;
    • 去掉9后总和7,是7的倍数,对应答案1;
    • 去掉3或4后的总和都不是7的倍数;
      正确答案是1,但你的代码输出2,导致错误。
  • 测试用例2:总和本身不能被X整除,但存在某个a[i]使得sum1 -a[i]能被X整除,且a[i]不是最小的袋子
    输入:

    1
    4 5
    6 7 3 4
    

    总和sum1=20?不,换总和sum1=21,X=5,r=1。袋子中有6(6%5=1),此时sum1-6=15,能被5整除,答案是3。你的代码排序后a[0]=3,r=1<=3,输出21//5=4,但实际sum1-3=18不是5的倍数,正确答案是3,你的代码输出错误。

  • 测试用例3:n=1时,袋子数量无法被X整除的情况
    输入:

    1
    1 10
    5
    

    你的代码判断5//10=0 <1,输出-1。但根据题目要求,如果允许买0个(总和0是X的倍数),答案应该是0;如果题目要求必须买正数量,输出-1。而题目样例3输入1 10 12输出1,说明你可能把题目理解成了“买任意数量的袋子,取最大的不超过总和的X的倍数”,这和原题要求完全不同,也是你代码错误的根源。

二、代码优化建议

作为编程初学者,你的代码在结构、效率和可读性上都有改进空间,结合正确的逻辑,给出以下建议:

1. 修正核心逻辑

按照题目正确要求,代码逻辑应该是:

#include <stdio.h>
#include <limits.h>

int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        int n, x;
        scanf("%d %d", &n, &x);
        int a[101];
        long long sum_total = 0; // 用long long避免总和溢出
        for (int i = 0; i < n; i++) {
            scanf("%d", &a[i]);
            sum_total += a[i];
        }
        
        int max_ans = -1;
        // 先检查买所有袋子的情况
        if (sum_total % x == 0) {
            max_ans = sum_total / x;
        }
        
        // 检查去掉每个袋子的情况
        for (int i = 0; i < n; i++) {
            long long current_sum = sum_total - a[i];
            if (current_sum == 0) continue; // 不买任何袋子,题目可能不允许
            if (current_sum % x == 0) {
                int current_ans = current_sum / x;
                if (current_ans > max_ans) {
                    max_ans = current_ans;
                }
            }
        }
        
        printf("%d\n", max_ans);
    }
    return 0;
}

2. 效率优化

  • 你的代码中使用了冒泡排序,时间复杂度是O(n²),但实际上我们不需要排序,只需要遍历每个袋子检查sum_total -a[i]是否能被X整除即可,时间复杂度降到O(n),更高效。
  • 使用long long存储总和,避免当n较大、a[i]较大时出现整数溢出的问题。

3. 代码可读性优化

  • 变量命名更清晰:比如sum_total代替sum1,max_ans代替s,让代码更容易理解。
  • 去掉不必要的分支:比如不需要单独处理n=1的情况,统一逻辑即可。
  • 注释关键步骤,方便自己和他人阅读代码。

4. 边界情况处理

  • 考虑总和为0的情况(比如所有袋子都被去掉,但题目不允许买0个,所以要跳过)。
  • 考虑整数溢出:当n=100,每个a[i]=1e9时,总和会超过int的范围(int最大约2e9),所以用long long存储总和是必要的。

内容的提问来源于stack exchange,提问作者Alpha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 17:32:51