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

Kattis卡牌交易问题Runtime Error排查求助

Kattis卡牌交易问题Runtime Error排查

我正在解决Kattis平台的卡牌交易问题,代码通过了前4个测试用例,但第5个测试用例触发了未知的Runtime Error。我通过Comparator对Type类排序后计算买入价和卖出价,希望定位出错代码行或了解触发错误的测试用例。

以下是我的代码:

import java.util.*;

class cardTrading {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int N = scanner.nextInt(); // 卡牌总数
        int T = scanner.nextInt(); // 卡牌类型数
        int K = scanner.nextInt(); // 需要凑齐的组合数

        int[] count = new int[N + 1];

        for (int i = 0; i < N; i++) {
            int number = scanner.nextInt();
            count[number]++;
        }

        ArrayList<Type> types = new ArrayList<>();

        for (int i = 1; i <= T; i++) {
            Long cost = scanner.nextLong();
            Long earn = scanner.nextLong();
            Type type = new Type(i, cost, earn);
            type.increment(count[type.getId()]);
            type.update();
            types.add(type);
        }

        Collections.sort(types, new TypeComparator());

        long profit = 0;

        for (int i = 0; i < K; i++) {
            Type type = types.get(i);
            profit -= type.getBuy();
        }
        for (int i = K; i < T; i++) {
            Type type = types.get(i);
            profit += type.getSell();
        }

        if (N == 1) {
            System.out.println(0);
        } else {
            System.out.println(profit);
        }
    }
}

class Type {
    private final int id;
    private Long buy;
    private Long sell;
    private int count;

    Type(int id, Long buy, Long sell) {
        this.id = id;
        this.buy = buy;
        this.sell = sell;
        this.count = 0;
    }

    int getId() {
        return id;
    }

    Long getBuy() {
        return buy;
    }

    Long getSell() {
        return sell;
    }

    int getCount() {
        return count;
    }

    void increment(int number) {
        this.count = this.count + number;
    }

    void update() {
        buy = (2 - count) * buy;
        sell = count * sell;
    }

    Long getDifference() {
        return buy + sell;
    }

    public int compareTo(Type type) {
        return this.getDifference().compareTo(type.getDifference());
    }

    public String toString() {
        return "Id: " + id + ", Buy: " + buy + ", Sell: " + sell + ", Count: " + count + ", Difference: " + this.getDifference();
    }
}

class TypeComparator implements Comparator<Type> {
    public int compare(Type type1, Type type2) {
        int difference = type1.compareTo(type2);
        if (difference == 0) {
            return type1.getBuy().compareTo(type2.getBuy());
        }
        return difference;
    }
}

可能的错误点及修复建议

1. 数组越界异常(最可能触发Runtime Error的原因)

定义count数组时使用了new int[N + 1],但卡牌类型编号的范围是1到T,当T > N时,访问count[number](number为卡牌类型编号)会超出数组索引范围,直接触发ArrayIndexOutOfBoundsException。

修复:将count数组长度改为T + 1,因为卡牌类型编号与类型总数T直接相关,和卡牌总数N无关:

int[] count = new int[T + 1];

2. 错误的特殊情况判断

代码末尾的if (N == 1)逻辑完全错误,即使只有1张卡牌,也可能需要买入/卖出卡牌来凑齐组合,利润不可能恒为0。这个判断不仅会输出错误结果,还可能在特定测试用例中触发逻辑异常。

修复:删除该判断,直接输出计算得到的profit:

System.out.println(profit);

3. 潜在的Long类型溢出

update()方法中buy = (2 - count) * buy和sell = count * sell如果数值过大,可能导致Long类型溢出。虽然这不会直接触发Runtime Error,但会导致计算结果错误,进而影响后续逻辑。可以使用Math.multiplyExact()来检测溢出并抛出异常,方便调试:

buy = Math.multiplyExact((2 - count), buy);
sell = Math.multiplyExact(count, sell);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 21:20:24