📅  最后修改于: 2023-12-03 15:28:48.734000             🧑  作者: Mango
代码题目链接:门 | 门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。