USACO青铜题Speeding Ticket:运行时错误及动态数组实现调试求助
问题分析与解决方案
一、运行时错误(输入环节)
从报错信息(数组索引越界)来看,核心原因是输入读取逻辑与题目要求不匹配,或硬编码数组长度导致超出范围,常见触发点:
- 未先读取路段数量(题目第一行应为两个整数:限速路段数n、实际行驶段数m),直接固定数组大小,当输入段数超过预设值时触发越界
- 输入读取顺序错误,比如先读速度再读里程,导致数据错位
- Scanner读取时未正确处理输入流,导致后续读取到空值
修复建议:
- 先读取第一行的n和m,再根据这两个值动态创建存储容器(而非固定大小数组)
- 按循环次数读取对应路段的里程和速度,确保每一组输入被正确解析
示例输入读取代码:
Scanner sc = new Scanner(System.in); int n = sc.nextInt(); // 限速路段总数 int m = sc.nextInt(); // 实际行驶路段总数 // 用ArrayList存储动态路段数据 ArrayList<int[]> limitSegments = new ArrayList<>(); for (int i = 0; i < n; i++) { int mile = sc.nextInt(); int speed = sc.nextInt(); limitSegments.add(new int[]{mile, speed}); } ArrayList<int[]> actualSegments = new ArrayList<>(); for (int i = 0; i < m; i++) { int mile = sc.nextInt(); int speed = sc.nextInt(); actualSegments.add(new int[]{mile, speed}); }
二、逻辑错误(动态数组对处理)
要处理动态数量的路段,核心是将里程区间展开,匹配每个区间的限速与实际车速,步骤如下:
- 将限速、实际行驶的路段都转换为「起始里程-结束里程-速度」的区间形式
- 用双指针遍历两个区间列表,找到重叠的里程区间,计算该区间内的超速值,记录最大值
核心逻辑代码:
int maxOverSpeed = 0; int limitIdx = 0; int actualIdx = 0; int prevMile = 0; // 遍历所有重叠里程区间 while (limitIdx < n && actualIdx < m) { int currentLimitEnd = limitSegments.get(limitIdx)[0]; int currentActualEnd = actualSegments.get(actualIdx)[0]; // 当前重叠区间的结束里程 int endMile = Math.min(currentLimitEnd, currentActualEnd); if (endMile > prevMile) { int limitSpeed = limitSegments.get(limitIdx)[1]; int actualSpeed = actualSegments.get(actualIdx)[1]; int overSpeed = actualSpeed - limitSpeed; if (overSpeed > maxOverSpeed) { maxOverSpeed = overSpeed; } } // 移动指针,处理完当前区间后推进到下一段 if (currentLimitEnd == endMile) { limitIdx++; } if (currentActualEnd == endMile) { actualIdx++; } prevMile = endMile; } System.out.println(maxOverSpeed);
测试验证
用示例输入(如:
3 3
10 60
20 30
30 60
15 65
25 40
30 70
)运行代码,输出结果为5,符合预期。
内容的提问来源于stack exchange,提问作者math_sp
相关产品推荐
相关产品推荐

