编程竞赛题求助:Powerpuff Girls配方计算代码调试优化
我帮你梳理一下代码里的几个关键问题,这些就是导致测试用例不通过的核心原因:
1. 数据类型溢出问题
题目明确说明原料数量可达到 LLONG_MAX(对应Java里的Long.MAX_VALUE),但你的代码全程用int存储数值。当原料数量超过int的最大值(约21亿)时,会直接引发NumberFormatException或错误的计算结果,这是大部分测试用例失败的主要原因。
2. 输入验证逻辑完全错误
你的validateIngredienInput方法里的判断条件写反了:
if (numOfIngredients <= LOWER_IDX && numOfIngredients <= UPPER_IDX)
LOWER_IDX是1,UPPER_IDX仅设为1e6(而题目要求N最大为1e7),这意味着合法的N(比如2)会触发退出逻辑,直接终止程序,完全违背了验证的初衷。
3. 内存与效率浪费
你用ArrayList存储所有原料的商再取最小值,当N达到1e7时,这个List会占用巨量内存,空间复杂度为O(N),不符合题目优化要求。其实只需要在遍历过程中实时记录最小值,就能把空间复杂度降到O(1)。
4. 输入读取效率低下
当N是1e7量级时,Scanner.nextLine()+split的方式会非常慢,甚至可能因内存不足无法处理超大字符串。应该用BufferedReader配合StringTokenizer读取输入,效率提升显著。
5. 重复解析与冗余操作
你在调用convertToIntegerArray转换原料数组后,又循环重新解析了一次,这完全是多余操作,且依然用int存储,没解决溢出问题。
6. 未处理除以0的异常
题目允许原料数量为0,如果制作一名小女警需要的某原料数量是0,直接做除法会抛出ArithmeticException,需要跳过这类原料的计算(因为不需要该原料,不限制制作数量)。
修正后的代码
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.StringTokenizer; public class PowerPuffGirls { private static final long MAX_N = 10_000_000L; public static void main(String[] args) { try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) { // 读取原料数量N int n = Integer.parseInt(br.readLine().trim()); // 验证N的合法性 if (n < 1 || n > MAX_N) { System.out.println(0); return; } // 读取制作所需的原料数量 StringTokenizer requiredTokenizer = new StringTokenizer(br.readLine().trim()); // 读取现有原料数量 StringTokenizer availableTokenizer = new StringTokenizer(br.readLine().trim()); long maxCount = Long.MAX_VALUE; for (int i = 0; i < n; i++) { long required = Long.parseLong(requiredTokenizer.nextToken()); long available = Long.parseLong(availableTokenizer.nextToken()); // 处理需要0单位原料的情况:不限制数量,跳过计算 if (required == 0) { continue; } // 计算当前原料能支持的最大数量 long current = available / required; // 更新最小值 if (current < maxCount) { maxCount = current; } } System.out.println(maxCount); } catch (IOException e) { e.printStackTrace(); System.out.println(0); } catch (Exception e) { // 处理其他异常,比如输入格式错误 System.out.println(0); } } }
关键修改说明
- 数据类型替换:全程用
long存储原料数量,彻底避免溢出问题。 - 输入优化:用
BufferedReader+StringTokenizer读取输入,效率远高于Scanner,适配大数量级输入场景。 - 空间优化:移除
ArrayList,仅维护一个maxCount变量,空间复杂度降至O(1)。 - 修正验证逻辑:正确判断N是否在1到1e7之间,不符合则输出0。
- 异常处理:增加对IO异常、格式异常的捕获,确保程序稳定性;同时处理了除以0的特殊情况。
内容的提问来源于stack exchange,提问作者user10035320

