1 条题解

  • 0
    @ 2026-6-19 10:30:39

    📝 题目大意

    给定一个仅由 ABC 组成的字符串 SS(保证三种字符均至少出现一次),从左到右扫描,找到第一次满足 ABC 都至少出现过一次的位置,输出该位置(1-indexed)。

    💡 解题思路

    1. 题目分析

      • N100N \leq 100,数据规模极小,直接模拟即可。
      • 题目保证 SS 一定包含 ABC 三种字符,因此无需考虑无解的情况。
      • 只需要找到三个字符首次全部出现的最早时刻,即三者中出现最晚的那个字符首次出现的位置。
    2. 算法推导

      • 维护三个布尔变量 seenAseenBseenC,分别表示 ABC 是否已经出现过,初始均为 false
      • 遍历字符串 SS(下标从 00 开始),每遇到一个字符,将对应的布尔标记置为 true
      • 每次更新标记后,检查 seenA && seenB && seenC 是否成立:
        • 若成立,则当前下标 ii 对应的位置 i+1i+1(1-indexed)即为答案,输出并 break 结束循环。
      • 由于题目保证有解,循环内一定会触发 break
    3. 边界与细节

      • 输出的是 1-indexed 位置,即 i+1i+1,而非 ii,这是常见 WA 点。
      • 找到答案后应立即 break 退出,避免输出多余内容。
      • 输入中 NN 虽然给出,但代码中无需显式使用 NN 作为循环边界之外的判断条件。

    ⏱️ 复杂度分析

    • 时间复杂度O(N)O(N),至多遍历整个字符串一次。
    • 空间复杂度O(1)O(1),仅使用常数个布尔变量。

    💻 标准代码 (C++)

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main() {
        int N;
        string S;
        cin >> N >> S;
    
        // 三个布尔标记,记录 A、B、C 是否已经出现过
        bool seenA = false, seenB = false, seenC = false;
    
        for (int i = 0; i < N; i++) {
            // 遇到对应字符,将标记置为 true
            if (S[i] == 'A') seenA = true;
            else if (S[i] == 'B') seenB = true;
            else if (S[i] == 'C') seenC = true;
    
            // 当三种字符都至少出现过一次时,输出当前位置(1-indexed)
            if (seenA && seenB && seenC) {
                cout << i + 1 << endl;
                break;
            }
        }
    
        return 0;
    }
    
    • 1

    信息

    ID
    732
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    (无)
    递交数
    1
    已通过
    1
    上传者