Codeforces 7E - Defining Macros 题解
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 题解的更多相关文章
- [Codeforces 7E] Defining Macros
Link:http://codeforces.com/problemset/problem/7/E Brief Introduction:一个表达式由多个“Macros”组成,每个Macro都为一个整 ...
- Codeforces Round #543 Div1题解(并不全)
Codeforces Round #543 Div1题解 Codeforces A. Diana and Liana 给定一个长度为\(m\)的序列,你可以从中删去不超过\(m-n*k\)个元素,剩下 ...
- Codeforces Round #545 Div1 题解
Codeforces Round #545 Div1 题解 来写题解啦QwQ 本来想上红的,结果没做出D.... A. Skyscrapers CF1137A 题意 给定一个\(n*m\)的网格,每个 ...
- Codeforces Round #539 Div1 题解
Codeforces Round #539 Div1 题解 听说这场很适合上分QwQ 然而太晚了QaQ A. Sasha and a Bit of Relax 翻译 有一个长度为\(n\)的数组,问有 ...
- [Codeforces Round #461 (Div2)] 题解
[比赛链接] http://codeforces.com/contest/922 [题解] Problem A. Cloning Toys [算法] 当y = 0 , 不可以 当 ...
- Educational Codeforces Round 64 部分题解
Educational Codeforces Round 64 部分题解 不更了不更了 CF1156D 0-1-Tree 有一棵树,边权都是0或1.定义点对\(x,y(x\neq y)\)合法当且仅当 ...
- Educational Codeforces Round 64部分题解
Educational Codeforces Round 64部分题解 A 题目大意:给定三角形(高等于低的等腰),正方形,圆,在满足其高,边长,半径最大(保证在上一个图形的内部)的前提下. 判断交点 ...
- 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]中有多少个数 ...
- Codeforces Good Bye 2016 题解
好久没有fst题了...比赛先A了前4题然后发现room里有人已经X完题了没办法只能去打E题,结果差一点点打完...然后C题fst掉了结果就掉rating 了...下面放题解 ### [A. New ...
随机推荐
- 2018HDU多校训练-3-Problem F. Grab The Tree
Little Q and Little T are playing a game on a tree. There are n vertices on the tree, labeled by 1,2 ...
- Java 将Excel转为图片、html、XPS、XML、CSV
通过文档格式转换,可满足不同办公场合对文档操作的需求.本文将介绍转换Excel文档为其他常见文档格式的方法.通过文中的方法,可支持将Excel转换为包括PDF.图片.html.XPS.XML.CSV. ...
- 如何在PHP框架里把Traits使用起来
我们都知道PHP只能使用单一继承,这意味着一个类只能从另一个类继承. 例如,您可能想从几个不同的类继承方法以防止代码重复. PHP 5.4中添加了新的语言特性Traits,而且它在Laravel框架 ...
- 【重大更新】AppWizard来了,emWin6.10版本来了
说明: 1.快圣诞节了,MDK和SEGGER都太生猛了,发布了大量软件更新,而且都是比较大的改进,待我周报再给大家分享. 2.不枉我这么多年对emWin的支持,官方也用心,终于带来AppWizard, ...
- python安装pymssql等包时出现microsoft visual c++ 14.0 is required问题无需下载visualcppbuildtools的解决办法
如题,在练习python安装一些包时,出现了microsoft visual c++ 14.0 is required问题.网上有很多资料:一是下载对应的.whl文件,然后pip install安装: ...
- python操作文件和目录查看、创建、删除、复制
python内置了os模块可以直接调用操作系统提供的接口函数,os.name查询的是操作系统,‘nt’表示windows系统 >>> import os >>> o ...
- 《漫画ERP》经典文章摘抄
1.对企业来说,应用ERP的价值就在于通过系统的计划和控制功能,结合企业的流程优化,有效的配置各项资源,以加快对市场的响应,降低成本,提高效率和效益,从而提升企业的竞争力:
- 平时常用sql
总结一下平时用到最多的sql语句 1.特殊日期 --今天凌晨 ,) --明天凌晨 ,,) --当周周一(每周从周日开始) ,) --当月的第一天 ,) --当月的最后一天 ,,,)) --今年的第一天 ...
- 关于css布局的记录(二) --网格布局
网格布局 学习来自阮一峰老师的教程网格布局和网络上的一些资料的学习 1.定义: 顾名思义,网格布局是将页面按行(row)和列(column)划分成一个个网格来进行布局 使用方法:display:gri ...
- Linux下执行脚本文件出现-bash: ./startup.sh: /bin/sh^M: 坏的解释器: 没有那个文件或目录
原因:脚本文件是在Windows环境下编辑的,windows环境下,每一行的结尾是\n\r,而Linux环境下,每一行结尾是\n.使用cat -A filename 可以看到每行的结尾后面多出了一 ...