Codeforces 7E - Defining Macros 题解

前言

开始使用博客园了,很想写点东西。(逃

这是一道Codeforces题目

做法

一道大模拟

相信大家都看得懂题目意思,我就不赘述了。

首先我们读进来\(n\)行,对于每一行,我们把它初步分成一下四块内容:

  • #
  • define
  • 宏的名字
  • 宏的表达式

注意:#define中间可能会有空格,define和宏的名字,宏的名字和宏的表达式之间一定会有空格。

现在我们来处理一下表达式,把它处理到一个序列内,这个序列包含:(,),+,-,*,/,变量,常量

对于每一个对象,我们可以如下定义:(优先级值越小越优先)

  • 变量,常量,括号:优先级为\(0\)
  • /,*:优先级为\(1\)
  • +,-:优先级为\(2\)
  • 宏:优先级为内部表达式的优先级

同时我们可以发现一个表达式,合法时满足以下条件:

  • /要求左侧对象优先级不大于1,右侧对象优先级等于0

  • *要求左侧对象优先级不大于1,右侧对象优先级不大于1

  • -要求右侧对象优先级不大于1

  • 其余对象不做要求

于是,对于一个表达式\(S\),我们可以递归地考虑:

  • 空表达式常量变量优先级\(0\),

  • 优先级为内部表达式优先级,合法也取决于内部表达式是否合法

  • (表达式),优先级为\(0\),合法取决于内部是否合法

  • 表达式+表达式表达式-表达式,合法取决于+,-的运算,优先级为\(2\)

  • 表达式/表达式表达式/表达式,合法取决于*,/的运算,优先级为\(1\)

好了,成了,可以写代码了!

程序

#include<bits/stdc++.h>
using namespace std; int n;
vector<string> expr[105];
//expr为id对应的处理好的表达式序列
int prio[105];
//prio为记忆化处理id对应的表达式的优先级
map<string,int> def;
//def为宏名称对应的id inline bool valid(int lp,char op,int rp){
//左表达式优先级lp,运算符op,右表达式优先级rp,是否合法
if(op=='/')return lp<=1&&rp<=0;
if(op=='*')return lp<=1&&rp<=1;
if(op=='+')return lp<=2&&rp<=2;
if(op=='-')return lp<=2&&rp<=1;
//cerr<<"OP INVALID"<<endl;
return false;
} int dfs(int id); inline bool isnumber(const string &s){
//string是否存入数字
for(int i=0;i<s.size();i++){
if(s[i]<'0'||s[i]>'9')return false;
}return true;
} inline bool ismacro(const string &s){
//string是否存入宏
return def.find(s)!=def.end();
} inline bool isvalue(const string &s){
//string是否存入变量
for(int i=0;i<s.size();i++){
if(!isalpha(s[i]))return false;
}return true;
} int parse(const vector<string> &v,int l,int r){
if(l>=r)return 0;//空表达式
if(l+1==r){//只有一个单独对象
if(isnumber(v[l])){//是常量
return 0;
}
if(ismacro(v[l])){//是宏
return dfs(def[v[l]]);
}
if(isvalue(v[l])){//是变量,要在宏后判断
return 0;
}
//cerr<<"PARSING: "<<v[l]<<endl;
//cerr<<"PARSE INVALID"<<endl;
return -1;//什么都不是,不可能出现这种情况(除非写错了)
}
if(v[l]=="("&&v[r-1]==")"){//被括号包裹
bool f=true;
int bkc=0;
for(int i=l;i<r;i++){//检查括号配对情况
if(v[i]=="(")bkc++;
if(v[i]==")")bkc--;
if(bkc==0&&i+1!=r){
f=false;
break;
}
}
if(f){
parse(v,l+1,r-1);
return 0;
}
}
int bkc=0;
for(int i=r-1;i>=l;i--){//优先找+、-,此处i从小到大亦可
if(v[i]==")")bkc++;
if(v[i]=="(")bkc--;
if(bkc)continue;//判断是否在括号内
if(v[i]=="+"){
if(valid(parse(v,l,i),'+',parse(v,i+1,r))){
return 2;
}else{
cout<<"Suspicious"<<endl;
exit(0);//不合法直接退出
}
}
if(v[i]=="-"){
if(valid(parse(v,l,i),'-',parse(v,i+1,r))){
return 2;
}else{
cout<<"Suspicious"<<endl;
exit(0);//不合法直接退出
}
}
}
for(int i=r-1;i>=l;i--){//再找*、/,此处i从小到大亦可
if(v[i]==")")bkc++;
if(v[i]=="(")bkc--;
if(bkc)continue;//判断是否在括号内
if(v[i]=="*"){
if(valid(parse(v,l,i),'*',parse(v,i+1,r))){
return 1;
}else{
cout<<"Suspicious"<<endl;
exit(0);//不合法直接退出
}
}
if(v[i]=="/"){
if(valid(parse(v,l,i),'/',parse(v,i+1,r))){
return 1;
}else{
cout<<"Suspicious"<<endl;
exit(0);//不合法直接退出
}
}
}
//cerr<<"PARSING: "<<l<<' '<<r<<endl;
//cerr<<"PARSE INVALID"<<endl;
return -1;//不可能出现的情况
} int dfs(int id){//记忆化计算id对应的表达式的优先级
//cerr<<"DFSING IN: "<<id<<endl;cerr<<prio[id]<<endl;
if(prio[id]!=-1)return prio[id];
return prio[id]=parse(expr[id],0,expr[id].size());
} vector<string> mkexp(const string &s){//处理原始字符串,获得表达式对象的序列
vector<string> res;
for(int i=0;i<s.size();i++){
if(s[i]==' '){
continue;
}
if(s[i]=='('){
res.push_back("(");
continue;
}
if(s[i]==')'){
res.push_back(")");
continue;
}
if(s[i]=='+'){
res.push_back("+");
continue;
}
if(s[i]=='-'){
res.push_back("-");
continue;
}
if(s[i]=='*'){
res.push_back("*");
continue;
}
if(s[i]=='/'){
res.push_back("/");
continue;
}
string tmp;
int j;
for(j=i;j<s.size()&&(isalpha(s[j])||(s[j]>='0'&&s[j]<='9'));j++){
tmp+=s[j];
}
res.push_back(tmp);
i=j-1;//常量,宏,变量都可以按照这个方式处理
}
return res;
} int main(){ ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0); cin>>n;
{
string s,t;char c;
getline(cin,s);
for(int i=1;i<=n;i++){
cin>>c>>s>>s;
//特判#号和define分开的情况
def[s]=i;
getline(cin,t);
expr[i]=mkexp(t);
}
getline(cin,t);
expr[0]=mkexp(t);
}
memset(prio,-1,sizeof(prio));
dfs(0);
cout<<"OK"<<endl;//由于不合法会退出,这里可以直接输出合法 return 0;
}

结尾

祝你们一次AC!虽然人家是写挂好多次的说。。。再看,再看就诅咒你也写挂!哼~

Codeforces 7E - Defining Macros 题解的更多相关文章

  1. [Codeforces 7E] Defining Macros

    Link:http://codeforces.com/problemset/problem/7/E Brief Introduction:一个表达式由多个“Macros”组成,每个Macro都为一个整 ...

  2. Codeforces Round #543 Div1题解(并不全)

    Codeforces Round #543 Div1题解 Codeforces A. Diana and Liana 给定一个长度为\(m\)的序列,你可以从中删去不超过\(m-n*k\)个元素,剩下 ...

  3. Codeforces Round #545 Div1 题解

    Codeforces Round #545 Div1 题解 来写题解啦QwQ 本来想上红的,结果没做出D.... A. Skyscrapers CF1137A 题意 给定一个\(n*m\)的网格,每个 ...

  4. Codeforces Round #539 Div1 题解

    Codeforces Round #539 Div1 题解 听说这场很适合上分QwQ 然而太晚了QaQ A. Sasha and a Bit of Relax 翻译 有一个长度为\(n\)的数组,问有 ...

  5. [Codeforces Round #461 (Div2)] 题解

    [比赛链接] http://codeforces.com/contest/922 [题解] Problem A. Cloning Toys          [算法] 当y = 0 ,   不可以 当 ...

  6. Educational Codeforces Round 64 部分题解

    Educational Codeforces Round 64 部分题解 不更了不更了 CF1156D 0-1-Tree 有一棵树,边权都是0或1.定义点对\(x,y(x\neq y)\)合法当且仅当 ...

  7. Educational Codeforces Round 64部分题解

    Educational Codeforces Round 64部分题解 A 题目大意:给定三角形(高等于低的等腰),正方形,圆,在满足其高,边长,半径最大(保证在上一个图形的内部)的前提下. 判断交点 ...

  8. Codeforces Beta Round #62 题解【ABCD】

    Codeforces Beta Round #62 A Irrational problem 题意 f(x) = x mod p1 mod p2 mod p3 mod p4 问你[a,b]中有多少个数 ...

  9. Codeforces Good Bye 2016 题解

    好久没有fst题了...比赛先A了前4题然后发现room里有人已经X完题了没办法只能去打E题,结果差一点点打完...然后C题fst掉了结果就掉rating 了...下面放题解 ### [A. New ...

随机推荐

  1. 曹工说Spring Boot源码系列开讲了(1)-- Bean Definition到底是什么,附spring思维导图分享

    写在前面的话&&About me 网上写spring的文章多如牛毛,为什么还要写呢,因为,很简单,那是人家写的:网上都鼓励你不要造轮子,为什么你还要造呢,因为,那不是你造的. 我不是要 ...

  2. 《一头扎进》系列之Python+Selenium框架设计篇1-什么是自动化测试框架-价值好几K的框架,不看别后悔,过时不候

    1. 什么是自动化测试框架 在了解什么是自动化测试框架之前,先了解一下什么叫框架?框架是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法:另一种定义认为,框架是可被应用开发者定制的 ...

  3. 解决oracle11g数据库监听连接不上问题

    java连接数据库报错12514,无法识别监听,但是PL客户端可以连接 oracle 监听 添加ip 同时修改tnsnames.ora.listener.ora将这两个文件中HOST后面的主机都修改为 ...

  4. JS基础-DOM

    DOM DOM 事件的级别 DOM 事件模型 DOM 事件流 DOM 事件捕获的具体流程 Event 对象的常见应用 自定义事件 DOM概述 | MDN DOM | MDN DOM操作 DOM事件级别 ...

  5. nginx之 nginx限流配置

    limit_req zone=req_zone;严格依照在limti_req_zone中配置的rate来处理请求超过rate处理能力范围的,直接drop表现为对收到的请求无延时limit_req zo ...

  6. 【JPA】开始

    Java SE中使用 实体Bean package cn.ycx.entity; import javax.persistence.Entity; import javax.persistence.I ...

  7. webpack实践(二)- webpack配置文件

    webpack系列博客中代码均在github上:https://github.com/JEmbrace/webpack-practice <webpack实践(一)- 先入个门> < ...

  8. 内网渗透教程大纲v1.0

    内网渗透 ☉MS14-068(CVE-2014-6324)域控提权利用及原理解析 ☉域控权限提升PTH攻击 未完待续...

  9. iOS Privacy Policy

    This application respects and protects the privacy of all users who use the service. In order to pro ...

  10. linux 常用Mysql脚本命令

    常用命令 无需系统Root权限 新数据库设置Root密码 visible > mysql -uroot -p visible > mysqladmin -uroot password &q ...