📜  门|门CS 2008 |第 83 题(1)

📅  最后修改于: 2023-12-03 15:28:48.734000             🧑  作者: Mango

门 | 门CS 2008 | 第 83 题

代码题目链接:门 | 门CS 2008 | 第 83 题

问题描述

大家都知道打开有些门需要输入几个按键的顺序密码。有一扇门的密码是 $4$ 位数字,其中有些数字。例如:$3**1$ 表明这个密码中,第一位和第四位都是 $3$,第三位和第四位都是 $1$。

现在给你若干组这样的密码,每组密码 $p$ 给出相应的数字个数和数字,以及这个密码是否被执行过的信息(对于每个密码,执行一次之后就会变成已经执行过了)。再给你一个指令集,指令可能是一个要求打开某个密码的命令(格式为open <密码>);也可能是一个要求撤销某个操作的命令(格式为close),撤销的最后一个操作也可以是一个打开密码的操作。请你写出一个程序,能够解决这个问题。

输入格式

第一行,为一个整数 $n$,表示以下有 $n$ 组数据。每组数据包括 $3$ 行。

第一行,为一个整数 $m$,表示这组数据中有 $m$ 个密码。

接下来的 $m$ 行,每行的格式为:输入格式: <电话号码的个数> <电话号码> <是否已执行>

例如,密码 $1$ 为:$4231$,且未被执行过,则对应的输入为:4 4231 0

第三行,为一个整数 $q$,表示这组数据中有 $q$ 条指令。

接下来的 $q$ 行代表 $q$ 条指令,可以为打开某个密码或者撤销某个操作。对于打开某个密码操作,格式为:open <密码>;对于撤销某个操作操作,格式为:close

数据保证指令集中,有且仅有一个打开某个密码的操作。

输出格式

如果遇到了不能执行的操作,则在一行中输出 Invalid,没有其他输出。如果指令集中的操作可以顺着执行下来,则在操作 open <密码> 之后输出操作的顺序,格式是每行一个数字,这些数字表示执行操作的顺序,按从前至后的顺序输出。

输入样例
2
2
4 3172 1
4 3902 0
2
open 317*
close
3
3 247 1
3 364 0
2
open 3*4
open 35**
open ****
输出样例

样例1输出:

Invalid

样例2输出:

2
1
实现思路

根据题意,首先需要判断给定的指令集是否合法。一个合法的指令集应该满足:

  • 它包含且只包含一个打开密码的操作
  • 所有的撤销操作都有所撤销,且操作顺序与输入的指令集相同。
  • 若有打开密码的操作,则在指令集中排在所有的撤销操作之前。

判断指令集是否合法之后,接下来需要模拟执行操作。我们可以利用一个栈来记录所有的操作,然后对这个栈进行操作也即对当前的所有操作进行操作。在操作栈的同时,我们还需要记录已经打开的密码,记录的方式可以使用一个列表。对于一个给定的密码,我们可以将它逐位匹配,如果这个密码可以被打开且还未被打开过,则标记这个密码已被打开。

对于判断一个密码是否匹配,我们可以使用 python 中的正则表达式,可以极大地方便此类问题的解决。此外,还需要注意特判一种情况,当指令集中只有撤销操作时,应该直接输出 Invalid

代码实现

代码实现过程中,我们使用两个栈,一个栈用于存储操作,一个栈用于存储已经执行了的操作(主要是为了方便实现撤销操作)。需要注意,由于需要查询手机号码是否匹配,因此需要使用正则表达式模块 re。