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
相关产品推荐
相关产品推荐

