CF7E Defining Macros

题目描述

大多数 C/C++ 程序员都知道预处理器的 #define 指令带来了极大的便利;但许多人也清楚,如果使用不当,#define 也可能导致问题。 在本题中,我们考虑一种 #define 结构(也称为宏)的模型。每个宏都有一个名字和一个值。声明宏的通用语法如下: #define 宏名 宏值 宏被声明后,程序中每次遇到“宏名”时,都会被替换为“宏值”(只会替换完整的单词,也就是说,只有当“宏名”被空格或其他非字母符号包围时才会发生替换)。在我们的模型中,“宏值”只能是由变量、四则运算、括号以及已经声明过的宏名组成的算术表达式(此时替换按顺序执行)。将宏名用其对应值替换的过程称为“替换”。 使用宏时的主要问题之一在于——替换后算术表达式的运算顺序被改变了,这一改变超出了某些宏自身的范围。 让我们看如下例子。假如有如下 #define 语句: #define sum x + y 接着在程序中计算表达式“2 * sum”。替换宏后得到“2 * x + y”,而直观上我们期望的是“2 * (x + y)”。 我们将这种情况称为“可疑”,即当宏替换后表达式的运算顺序发生了变化,并超出了某个宏自身的范围。因此,你的任务是:给定一组 #define 定义和一个表达式,请判断该表达式是否属于“可疑”情况。 更正式地说。我们对给定表达式进行一次普通的宏替换。此外,我们还可以进行“安全的”宏替换:用括号将每一个被替换的宏值括起来。随后,按照算术中括号展开的规则,我们可以省去部分括号。如果存在一种方法,使我们得到的表达式能够与普通替换后的表达式完全一致(逐字符完全一致,但不考虑空格),那么该表达式及所给的宏系统被称为“正确”的,否则就叫“可疑”。 注意,除法“/”在此题中被视为普通的数学除法,而非 C/C++ 中的整数除法。因此,例如表达式“a*(b/c)”去掉括号后也可以写成“a*b/c”。

输入格式

第一行包含一个整数 $n$($0 \leq n \leq 100$),表示给定程序中的 #define 结构的数量。 接下来 $n$ 行,每行给出一个 #define 结构。每个结构遵循如下语法: #define 名称 表达式 其中: - 名称——宏的名字; - 表达式——该宏要被替换成的表达式。表达式是一个非空字符串,包含数字、变量名、已声明宏名、圆括号与 '+-\*/' 运算符。保证替换前后表达式均为正确的算术表达式,不含一元操作。表达式仅由不超过 $10^9$ 的非负整数构成。 所有名字(无论是 #define 的名字还是变量名)均为大小写敏感的拉丁字母字符串。保证所有变量名都与 #define 的名字不同。 最后一行为需检查的表达式。该表达式也是非空字符串,满足与 #define 中表达式相同的限制。 输入的每行中,除“define”单词、构造和变量名字以外的其他任何位置都可以有任意数量的空格,尤其是在 '#' 前后都可以有任意数量的空格。 输入文件中每行长度均不超过 100 个字符。

输出格式

如果该表达式在上述判定下是“正确”的,则输出 “OK”;否则输出 “Suspicious”。

说明/提示

由 ChatGPT 5 翻译