题意翻译

题目给了一系列C + +的宏定义,问你一个表达式是否是“安全"的。安全的定义是,展开后的表达式中,所有的宏在计算过程中都被作为一个整体运算。

如#define sumx十y后,2 sum就会被替换乘2x+y 此时此时因为乘号优先级比加号高,导致宏在实际计算中被拆开了,可能产生错误。

宏的个数<=10,每个表达式长度<=10.只有四则运算和括号。

Translated by liyifeng

题目描述

Most C/C++ programmers know about excellent opportunities that preprocessor #define directives give; but many know as well about the problems that can arise because of their careless use.

In this problem we consider the following model of #define constructions (also called macros). Each macro has its name and value. The generic syntax for declaring a macro is the following:

#define macro_name macro_value

After the macro has been declared, "macro_name" is replaced with "macro_value" each time it is met in the program (only the whole tokens can be replaced; i.e. "macro_name" is replaced only when it is surrounded by spaces or other non-alphabetic symbol). A "macro_value" within our model can only be an arithmetic expression consisting of variables, four arithmetic operations, brackets, and also the names of previously declared macros (in this case replacement is performed sequentially). The process of replacing macros with their values is called substitution.

One of the main problems arising while using macros — the situation when as a result of substitution we get an arithmetic expression with the changed order of calculation because of different priorities of the operations.

Let's consider the following example. Say, we declared such a #define construction:

#define sum x + y

and further in the program the expression "2 * sum" is calculated. After macro substitution is performed we get "2 * x + y", instead of intuitively expected "2 * (x + y)".

Let's call the situation "suspicious", if after the macro substitution the order of calculation changes, falling outside the bounds of some macro. Thus, your task is to find out by the given set of #define definitions and the given expression if this expression is suspicious or not.

Let's speak more formally. We should perform an ordinary macros substitution in the given expression. Moreover, we should perform a "safe" macros substitution in the expression, putting in brackets each macro value; after this, guided by arithmetic rules of brackets expansion, we can omit some of the brackets. If there exist a way to get an expression, absolutely coinciding with the expression that is the result of an ordinary substitution (character-by-character, but ignoring spaces), then this expression and the macros system are called correct, otherwise — suspicious.

Note that we consider the "/" operation as the usual mathematical division, not the integer division like in C/C++. That's why, for example, in the expression "a*(b/c)" we can omit brackets to get the expression "a*b/c".

输入输出格式

输入格式:

The first line contains the only number nn ( 0<=n<=1000<=n<=100 ) — the amount of #define constructions in the given program.

Then there follow nn lines, each of them contains just one #define construction. Each construction has the following syntax:

#define name expression

where

  • name — the macro name,
  • expression — the expression with which the given macro will be replaced. An expression is a non-empty string, containing digits,names of variables, names of previously declared macros, round brackets and operational signs +-*/. It is guaranteed that the expression (before and after macros substitution) is a correct arithmetic expression, having no unary operations. The expression contains only non-negative integers, not exceeding 10^{9}109 .

All the names (#define constructions' names and names of their arguments) are strings of case-sensitive Latin characters. It is guaranteed that the name of any variable is different from any #define construction.

Then, the last line contains an expression that you are to check. This expression is non-empty and satisfies the same limitations as the expressions in #define constructions.

The input lines may contain any number of spaces anywhere, providing these spaces do not break the word "define" or the names of constructions and variables. In particular, there can be any number of spaces before and after the "#" symbol.

The length of any line from the input file does not exceed 100 characters.

输出格式:

Output "OK", if the expression is correct according to the above given criterion, otherwise output "Suspicious".

输入输出样例

输入样例#1: 复制

1
#define sum x + y
1 * sum

输出样例#1: 复制

Suspicious

输入样例#2: 复制

1
#define sum  (x + y)
sum - sum

输出样例#2: 复制

OK

输入样例#3: 复制

4
#define sum  x + y
#define mul  a * b
#define div  a / b
#define expr sum + mul * div * mul
expr

输出样例#3: 复制

OK

输入样例#4: 复制

3
#define SumSafe   (a+b)
#define DivUnsafe  a/b
#define DenominatorUnsafe  a*b
((SumSafe) + DivUnsafe/DivUnsafe + x/DenominatorUnsafe)

输出样例#4: 复制

Suspicious

题解思维

考虑什么时候会Suspicious
如果是l/r, 当ll有+or-或r有+or-or*or/就会出错。
(有指的是最外一层)
其他同理。
所以只要dp,记录最外一层是否存在+or-,*or/即可。
预处理每个左括号对应的右括号。
复杂度线性。
读入有点麻烦。

将这个程序翻译过来,就是 (((a+b))+a/b/a/b+x/a*b)

在这个程序中,a/b/a/b和x/a*b可能会出现错误,这是由运算符之间的关系造成的。

我们可以观察一下四种运算,可以发现情况可以分为四种。

  1. 完全正确

  2. 完全不正确

  3. 在减号后或与乘除相连时出错

  4. 在除号后出错

我们找到一个宏定义表达式的优先级最后运算符,把式子分为两部分,如果两部分都是第2种情况,那整个式子也是第2种。

如果运算符为加,整个式子会是第3种情况。

如果运算符为减,则仅当右部是第3种情况时,整体为第2种情况,否则整体为第3种情况。

如果运算符为乘,则在两部分至少有一个为第3种情况时,整体为第2种情况,否则整体为第3种情况。

如果运算符为除,则在两部分至少有一个为第3种情况或右部为第4种情况时,整体为第2种情况,否则整体为第3种情况。

如果两端有括号,先去括号,判断括号中的表达式的种类,没有的话就是第一种情况。

最后对最后那个程序进行判断,如果是第2种情况,就是不正确,否则就是正确。

Accept Code:

#include<bits/stdc++.h>
using namespace std;
map<string,int> mapp;
int n,m;
string s,s1,s2,ss,s3;
int judge(int l,int r)
{int flag=0,pos=0;for (int i=r;i>=l;i--){if (s[i]=='(') flag++;if (s[i]==')') flag--;if (pos==0&&flag==0&&(s[i]=='*'||s[i]=='/')) pos=i;if (flag==0&&(s[i]=='+'||s[i]=='-')){int t1=judge(l,i-1),t2=judge(i+1,r);if (t1==2||t2==2) return 2;if (s[i]=='+') return 3;if (s[i]=='-'&&t2==3) return 2;if (s[i]=='-') return 3;}}if (pos!=0){int t1=judge(l,pos-1),t2=judge(pos+1,r);if (t1==2||t2==2) return 2;if (s[pos]=='*'&&(t1==3||t2==3)) return 2;if (s[pos]=='*') return 4;if (s[pos]=='/'&&(t1==3||t2==3||t2==4)) return 2;if (s[pos]=='/') return 4;}else if (s[l]=='('&&s[r]==')'){if (judge(l+1,r-1)==2) return 2;else return 1;}else{ss="";for (int i=l;i<=r;i++)ss+=s[i];if (mapp[ss]!=0) return mapp[ss];else return 1;}
}
int main()
{cin>>n;for (int i=1;i<=n;i++){int tot=0;int t1=0,t2=0;int j=1;cin>>s1;if (s1[s1.length()-1]=='#') cin>>s1;cin>>s1;getline(cin,s2);s="";for (int j=0;j<=s2.length()-1;j++)if (s2[j]!=' ') s+=s2[j];int ans=judge(0,s.length()-1);mapp[s1]=ans;}int tot=0;s3="";s="";getline(cin,s3);for (int i=0;i<s3.length();i++)if (s3[i]!=' ') s+=s3[i];int ans=judge(0,s.length()-1);if (ans!=2) printf("OK\n");else printf("Suspicious\n");return 0;
} 

洛谷 CF7E Defining Macros 题解相关推荐

  1. 洛谷P2507 [SCOI2008]配对 题解(dp+贪心)

    洛谷P2507 [SCOI2008]配对 题解(dp+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1299251 链接题目地址:洛谷P2507 [S ...

  2. 洛谷P2312 解方程题解

    洛谷P2312 解方程题解 题目描述 已知多项式方程: \[a_0+a_1x+a_2x^2+\cdots+a_nx^n=0\] 求这个方程在 \([1,m]\) 内的整数解(\(n\) 和 \(m\) ...

  3. 洛谷P1273 有线电视网 题解

    洛谷P1273 有线电视网 题解 题目链接:P1273 有线电视网 题意: 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为 ...

  4. 洛谷P4568 [JLOI2011] 飞行路线 题解

    洛谷P4568 [JLOI2011] 飞行路线 题解 题目链接:P4568 [JLOI2011] 飞行路线 题意: Alice 和 Bob 现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公 ...

  5. 洛谷P3426 [POI2005]SZA-Template 题解

    洛谷P3426 [POI2005]SZA-Template 题解 题目链接:P3426 [POI2005]SZA-Template 题意:你打算在纸上印一串字母. 为了完成这项工作,你决定刻一个印章. ...

  6. 洛谷P1156 垃圾陷阱 题解浅谈刷表法与填表法

    洛谷P1156 垃圾陷阱 题解&浅谈刷表法与填表法 填表法 :就是一般的动态规划,当前点的状态,可以直接用状态方程,根据之前点的状态推导出来. 刷表法:由当前点的状态,更新其他点的状态.需要注 ...

  7. 洛谷P1262 间谍网络题解

    洛谷P1262 间谍网络题解 题目大意 题目描述 由于外国间谍的大量渗入,国家安全正处于高度的危机之中.如果 A 间谍手中掌握着关于 B 间谍的犯罪证据,则称 A 可以揭发 B.有些间谍收受贿赂,只要 ...

  8. 【洛谷P3960】列队题解

    [洛谷P3960]列队题解 题目链接 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有 n×m ...

  9. 洛谷P4099 [HEOI2013]SAO 题解

    洛谷P4099 [HEOI2013]SAO 题解 题目链接:P4099 [HEOI2013]SAO 题意: Welcome to SAO ( Strange and Abnormal Online). ...

最新文章

  1. java连接mysql执行ddl_Mysql 执行DDL导致Waiting for table metadata lock
  2. Builder 建造者模式
  3. 去掉windows console application的dos显示
  4. Python 解LeetCode:23. Merge k Sorted Lists
  5. php显示动态通告信息方式,Joomla PHP通知,警告和错误指南
  6. 如何在PD17虚拟机上安装CentOS Linux系统
  7. [转载] 七龙珠第一部——第019话 天下第一武道会开始
  8. 《软件构架实践》阅读笔记4
  9. spring源码解析(一)---占位符解析替换
  10. keli不支持中文,显示中文乱码
  11. 肇庆学院计算机类宿舍哪里,肇庆学院宿舍怎么样 住宿条件好不好
  12. 基于UDP的网络对战五子棋
  13. 网页压缩 - GZIP
  14. 尺寸公差分析尺寸链计算软件:新能源电池行业—模组散热系统之弹簧长度计算
  15. 计算机组成,南北桥,倍频,通信,频率一致才可以通信
  16. 关于video设置autoplay属性无法自动播放问题
  17. 打造智慧工地,低代码平台助力基建行业全链路数字化升级
  18. pycharm 使用matplotlib 绘图时图片不能显示中文
  19. Mysql 面试题总结
  20. Microsoft project下载

热门文章

  1. 八、jQuery的QQ音乐播放器
  2. 获取Excel单元格存储日期格式数据
  3. 一本通 第三部分 数据结构 第四章 图论算法 第二节 最短路径算法 1381:城市路(Dijkstra)
  4. 基于Jetson NX的模型部署
  5. 网络教育计算机统考-多媒体技术操作题
  6. 《我是一只IT小小鸟》读后感,献给要正在找工作的有缘朋友
  7. liferay开发环境搭建
  8. 64位系统 system32 和 syswow64
  9. 桌面上的Internet explorer图标删不掉
  10. 论文速读之QUALITY-GATED CONVOLUTIONAL LSTM FOR ENHANCING COMPRESSED VIDEO