1 条题解
-
0
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
- 上传者