修复 Codeforces 2190A 中的运行时错误 | AI生成和翻译

Home 2026.01

Question: 为什么这段代码在 Codeforces problem 2190A 的 test 1 中出现了 Runtime Error?

Answer:

你的代码在 test 1 出现 Runtime Error 主要是因为这个关键的逻辑错误:

for (i = 0; i < n; i++) {
    char target;
    if (i < zero) {
        target = '0';
    } else {
        target = '1';
    }
    if (s.charAt(i) != target) {
        positions.add(i);
    }
}

这个逻辑假设在排序后,字符串应该变为:

但这不是题目所要求的。

该题目要求的是通过最多一次交换两个字符,能够获得的lexicographically smallest(字典序最小)的字符串。

这意味着目标排序字符串始终是:

所有的 ‘0’ 都在所有的 ‘1’ 之前
000...0111...1(恰好是 zero 个 0 后面跟着 one 个 1)

但你的代码是将当前字符串与这个理想的排序字符串进行比较,并收集所有不匹配的位置。

这对于该问题的目的来说是完全错误的,因为:

你的代码几乎总是输出超过两个位置(或者零个),这导致:

test 1 出现 Runtime Error 的真实原因

很可能 test 1 是以下这些简单情况之一:

1
3
010

1
4
1100

1
1
0

在这些情况下,你的代码:

正确思路(简述)

你只需要找到最多一个位置错误的、在 ‘0’ 之前的 ‘1’

如果字符串是非递减的(所有的 0 都在 1 之前),那么字符串已经符合要求(Bob)。

否则,你通常需要将一个出现得太早的 ‘1’一个出现得太晚的 ‘0’ 进行交换。

最常见的模式:找到应该为 ‘0’ 的最左边的 ‘1’,以及应该为 ‘1’ 的最右边的 ‘0’,然后交换它们。

但你必须检查在进行这一次交换后,字符串是否变得有序。

快速正确的方案

Read t
For each test:
    Read n, s
    Count zeros = count of '0'
    
    // 检查是否已经有序 (non-decreasing)
    boolean sorted = true;
    for (int i = 1; i < n; i++) {
        if (s.charAt(i) < s.charAt(i-1)) {
            sorted = false;
            break;
        }
    }
    
    if (sorted) {
        out.println("Bob");
        continue;
    }
    
    // 寻找我们拥有 '1' 但在 target 中应该是 '0' 的最左侧位置
    int left = -1;
    for (int i = 0; i < zeros; i++) {
        if (s.charAt(i) == '1') {
            left = i;
            break;
        }
    }
    
    // 寻找我们拥有 '0' 但在 target 中应该是 '1' 的最右侧位置
    int right = -1;
    for (int i = n-1; i >= zeros; i--) {
        if (s.charAt(i) == '0') {
            right = i;
            break;
        }
    }
    
    // 如果两个都找到了 → 一次交换即可修复
    if (left != -1 && right != -1) {
        out.println("Alice");
        out.println((left+1) + " " + (right+1));
    } else {
        out.println("Bob");  // 一次交换无法完成
    }

这并不是 100% 完整的代码(某些边界情况需要仔细检查),但它解释了解决方向。

你当前的代码正在尝试做一些与题目要求完全不同的事情,这就是它很早就失败(test 1)的原因。

References:


Back

x-ai/grok-4.1-fast

Donate