1 条题解

  • 0
    @ 2025-11-19 22:42:54

    1. 核心观察

    由于有无限多的人,当我们遇到 ? 时,理论上总是可以将其解释为一个新人进入,或者解释为一个之前进入过但未记录的人离开。这给了我们很大的灵活性。

    但是,我们仍然需要检查记录的合法性。主要矛盾在于:

    对于确定的记录 I x,如果 x 已经在大楼内,则这是非法的(重复进入)。

    对于确定的记录 O x,如果 x 不在大楼内,则这是非法的(未进入先离开)。

    2. 贪心策略

    对于不确定的记录 ?,我们需要决定如何解释它(是进入还是离开)才能最大限度地避免错误。

    贪心原则:

    当遇到 ? 时,我们优先将其解释为 一个新人进入。

    只有在无法解释为进入时(比如大楼内人数已经达到可能的最大值),才将其解释为离开。

    为什么这样贪心?

    解释为进入总是安全的,因为新人无限多。

    解释为离开需要有一个对应的人在大楼内,如果我们过早地解释为离开,可能会让后面真正的离开操作没有对应的人。

    3. 具体实现

    我们可以维护以下信息:

    inside:一个集合,记录当前确定在大楼内的人。

    unknown_enter:一个栈,记录那些被解释为进入的不确定记录的位置。这样当需要解释为离开时,我们可以匹配最近的进入。

    算法流程:

    遍历每条记录(从第 1 条到第 m 条):

    如果是 I x:

    如果 x 已经在 inside 中 → 发现错误,输出当前行号。

    否则,将 x 加入 inside。

    如果是 O x:

    如果 x 在 inside 中 → 从 inside 移除 x。

    否则,如果有之前解释为进入的 ?(unknown_enter 栈非空)→ 弹出栈顶,表示那个 ? 实际上是 x 的进入记录。

    否则 → 发现错误,输出当前行号。

    如果是 ?:

    先尝试解释为进入:将其位置压入 unknown_enter 栈。

    但要注意:大楼内总人数不能超过当前记录数的一半(因为进出要平衡)。

    如果遍历完所有记录都没有发现错误,输出 -1。

    4. 关键点说明

    为什么需要检查人数限制?因为如果大楼内人数过多,后面没有足够的离开操作来匹配,最终会导致错误。

    栈的作用:后进先出的特性正好匹配"最近进入的人先离开"的逻辑。

    时间复杂度:O(m),每个记录处理时间是常数(使用哈希集合和栈)。

    样例分析

    样例 5:

    text 2 I 2 O 1 第1行:I 2 → 2进入大楼,inside = {2}

    第2行:O 1 → 1不在大楼内,且没有?可以借用 → 错误,输出2

    样例 3:

    text 2 ? O 1 第1行:? → 压入栈,unknown_enter = [1]

    第2行:O 1 → 1不在inside,但栈非空 → 弹出栈顶,匹配成功

    总结

    这道题的关键在于理解无限多人提供的灵活性,以及如何用贪心策略处理不确定记录。通过维护当前大楼内的人员集合和一个未知进入记录的栈,我们可以在O(m)时间内检测出第一条错误记录。

    • 1

    信息

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