在Kattis平台提交Java代码出现Runtime Error,请求排查
Kattis提交代码出现Runtime Error排查求助
我在Kattis平台提交代码时遇到了Runtime Error,但所有测试用例在本地机器上均运行正常。已进行全面测试,但一提交至Kattis就报错,调试数小时仍未解决,恳请帮忙排查。
代码如下:
import java.util.*; import java.io.*; public class GOT{ public static void main(String[] args)throws IOException{ BufferedReader bi = new BufferedReader(new InputStreamReader(System.in)); int[] parseLine1 = new int[2]; String[] strLine1; strLine1 = bi.readLine().split(" "); //Parsing of 1st line of inputs i.e. N and K for (int i = 0; i < strLine1.length; i++) { parseLine1[i] = Integer.parseInt(strLine1[i]); } //init of Kids array int[] nKids = new int[parseLine1[0]]; String[] commands = new String[parseLine1[1]]; int i; for(i = 0; i < nKids.length; i++){ nKids[i] = i; } //parsing of 2nd line which are the commands String strLine2; String[] nCommands; Scanner sc = new Scanner(System.in); strLine2 = sc.nextLine(); nCommands = strLine2.split(" "); int holder=0; ArrayList<Integer> tracker = new ArrayList<Integer>(); int exit; int throwns; int undoCtr=0; for(i = 0; i<nCommands.length; i++){ if(nCommands[i].equals("undo")){ nCommands[i] = nCommands[i].replaceAll("undo","101"); } } exit = nCommands.length; i = 0; while(exit != 0){ //System.out.println(Integer.parseInt(nCommands[i])); if(Integer.parseInt(nCommands[i]) > 0){ for(int k = 0; k< Integer.parseInt(nCommands[i]); k++){ holder++; if(holder==nKids.length){ holder = 0; } } }if(Integer.parseInt(nCommands[i]) < 0){ for(int k = Integer.parseInt(nCommands[i]); k<0 ; k++){ holder--; if(holder==0){ holder = nKids.length; } } }else if(Integer.parseInt(nCommands[i]) == 101){ i++; undoCtr = Integer.parseInt(nCommands[i]); while(undoCtr!=0){ tracker.remove(tracker.size()-1); undoCtr--; } exit--; } tracker.add(holder); exit--; i++; } System.out.println(tracker.get(0)); } }
问题排查与修复建议
1. 输入读取方式冲突
混合使用BufferedReader和Scanner读取输入,可能导致第二行输入读取不完整或为空。比如BufferedReader.readLine()读取第一行后,输入流中剩余的换行符会被Scanner.nextLine()读取,导致nCommands数组为空,后续解析时抛出NumberFormatException或数组越界错误。
修复: 统一使用BufferedReader读取所有输入:
// 替换原第二行读取代码 String strLine2 = bi.readLine(); String[] nCommands = strLine2.split(" ");
2. 负数移动逻辑错误
处理负数移动时,holder--后如果等于-1,代码错误地将其设置为nKids.length,而数组索引范围是0到nKids.length-1,这会导致后续操作中索引越界。
修复: 调整负数移动的边界处理:
if(Integer.parseInt(nCommands[i]) < 0){ for(int k = Integer.parseInt(nCommands[i]); k<0 ; k++){ holder--; if(holder < 0){ // 当holder小于0时,循环到数组末尾 holder = nKids.length - 1; } } }
3. Undo操作的越界风险
当undo的次数超过tracker中已存储的元素数量时,tracker.remove(tracker.size()-1)会抛出IndexOutOfBoundsException。
修复: 添加边界检查,确保undo次数不超过tracker的大小:
while(undoCtr!=0 && !tracker.isEmpty()){ tracker.remove(tracker.size()-1); undoCtr--; }
4. 冗余代码与逻辑错误
nKids数组完全未被使用,可以直接删除,用parseLine1[0]表示孩子数量。- 处理"undo"时替换为"101"的方式冗余,直接判断字符串是否为"undo"即可,避免额外的字符串转换。
- 原代码中undo操作后仍会执行
tracker.add(holder),这会导致错误的状态被记录,需调整为:只有非undo的操作才添加状态到tracker,undo操作是撤销之前的状态,不需要添加新状态。
修复后的完整代码
import java.util.*; import java.io.*; public class GOT { public static void main(String[] args) throws IOException { BufferedReader bi = new BufferedReader(new InputStreamReader(System.in)); String[] strLine1 = bi.readLine().split(" "); int kidCount = Integer.parseInt(strLine1[0]); int commandCount = Integer.parseInt(strLine1[1]); String[] nCommands = bi.readLine().split(" "); int currentPosition = 0; ArrayList<Integer> tracker = new ArrayList<>(); int i = 0; while (i < nCommands.length) { String cmd = nCommands[i]; if (cmd.equals("undo")) { int undoTimes = Integer.parseInt(nCommands[i + 1]); // 撤销指定次数的操作,最多撤销tracker中的所有记录 for (int j = 0; j < undoTimes && !tracker.isEmpty(); j++) { tracker.remove(tracker.size() - 1); } // 恢复到撤销后的位置 currentPosition = tracker.isEmpty() ? 0 : tracker.get(tracker.size() - 1); i += 2; // 跳过undo和后面的数字 } else { int steps = Integer.parseInt(cmd); if (steps > 0) { currentPosition = (currentPosition + steps) % kidCount; } else { currentPosition = (currentPosition + steps) % kidCount; if (currentPosition < 0) { currentPosition += kidCount; } } tracker.add(currentPosition); i++; } } System.out.println(currentPosition); } }
内容的提问来源于stack exchange,提问作者user14997606
相关产品推荐
相关产品推荐

