uoj98未来程序改 纯暴力不要想了
暴力模拟A了,数据还是良(shui)心(shui)的
90分的地方卡了半天最后发现一个局部变量被我手抖写到全局去了,,,
心碎*∞
没什么好解释的,其实只要写完表达式求值(带函数和变量的),然后处理一下高维数组
给变量和函数各开一个map(事实上我给每一层都开了一个变量的map,每次都复制一下,但还是没有T也没有M)
终于写完了
记得有人立了个flag说我联赛前调不完这道题,终于拆了
#include <bits/stdc++.h>
#define st(now) ((isvar[now])?var[st[now]]:st[now])
using namespace std;
int In,input[],len,dep=,funsum,retu,PA,read=;bool RETU,debug;char ch;
int varsum[],var[],funstart[],pa[],pasum[],wei[][],weisum[];
string par[][],code;
set<char> s1;//实词集合(控制、函数、变量)
set<char> s2;//表达式字符集合
set<char> s3;//数字集合
map<string,int> m1[];//变量映射
map<string,int> m2;//函数映射
void init()//初始化
{
freopen("1.in","r",stdin);
// freopen("1.out","w",stdout);
scanf("%d",&In);
for(int i=;i<=In;i++)
scanf("%d",&input[i]);
bool flag=;
for(char ch=getchar();ch!=EOF;ch=getchar())
if(flag && ch==';') flag=;
else if(!flag) code+=ch;
for(char ch='a';ch<='z';ch++) s1.insert(ch),s2.insert(ch);
for(char ch='A';ch<='Z';ch++) s1.insert(ch),s2.insert(ch);
for(char ch='';ch<='';ch++) s1.insert(ch),s2.insert(ch),s3.insert(ch);
s1.insert('_');s2.insert('_');
s2.insert('(');s2.insert(')');
s2.insert('+');s2.insert('-');s2.insert('*');s2.insert('/');s2.insert('%');
s2.insert('!');s2.insert('&');s2.insert('|');s2.insert('=');s2.insert('<');s2.insert('>');s2.insert('^');
s2.insert('[');s2.insert(']');
code.erase(,);
for(int i=;i<=code.length();)
if((code[i]==' '||code[i]=='\n'||code[i]=='\t')&&((!s1.count(code[i-])) || (!s1.count(code[i+]))))
code.erase(i,);
else i++;
varsum[]=;len=code.length();RETU=;PA=;
}
int level(int &now)//符号转成运算级
{
switch(code[now])
{
case'<':if(code[++now]=='=')return ;
else {now--;return ;}
case'>':if(code[++now]=='=')return ;
else {now--;return ;}
case'=':if(code[++now]=='=')return ;
else {now--;return ;}
case'!':now++;return ;
case'|':now++;return ;
case'&':now++;return ;
case'^':return ;
case'+':return ;
case'-':return ;
case'*':return ;
case'/':return ;
case'%':return ;
}
}
bool dayu(int a,int b)
{
if(a==) return ;
if(a>=b) return ;
if((a==)&&(b==))return ;
if((a>=)&&(a<=)&&(b>=)&&(b<=)) return ;
if((a==)&&(b==)) return ;
if((a>=)&&(a<=)&&(b>=)&&(b<=)) return ;
return ;
}
int word(int now)//找下一个单词(变量 int 函数之类的)
{
int end;
for(end=now;s1.count(code[end]);end++);
return end;
}
int express(int now)//找下一个表达式
{
int end;
for(end=now;s2.count(code[end]);end++);
return end;
}
int pass(int now)
{
while(code[now]!=';') now++;
return now+;
}
int block(int now)//跳过一段程序
{
if(code[now]=='{')
{
int dep=;
for(now++;dep;now++) if(code[now]=='{') dep++;else if(code[now]=='}') dep--;
return now;
}
else
{
int next=word(now);
if((next-now== && code.substr(now,)=="for")||(next-now== && code.substr(now,)=="while"))
{
int p=next+,deep=;
while(deep)
{
if(code[p]=='(') deep++;
if(code[p]==')') deep--;
p++;
}
return block(p);
}
else
if(next-now== && code.substr(now,)=="if")
{
int p=next+,deep=;
while(deep)
{
if(code[p]=='(') deep++;
if(code[p]==')') deep--;
p++;
}
p=block(p);
next=word(p);
if(next-p== && code.substr(p,)=="else")
return block(next);
else return p;
}
else
{
int p=now;
while(code[p]!=';') p++;
return p+;
}
}
}
int num(int &now)//得到最近的十进制数
{
int sum=;
while(s3.count(code[now]))
sum=sum*+code[now++]-'';
return sum;
}
int getsize(int &now,int k)//得到数组的大小
{
int sum=;
while(code[now]=='[')
{
now++;
int tem=num(now);
wei[k][++weisum[k]]=tem;
sum*=tem;
now++;
}
return sum;
}
int focus(int &next,int first)//得到所要的变量在数组中的位置
{
int calc(int &now);
int sum=,SUM=,i=;
if(code[next]=='[')
{
while(code[next]=='[')
{
next++;i++;
sum+=SUM*calc(next);
SUM*=wei[first][i];
next++;
}
}
return sum;
}
int newfun(int beg,int end)//定义新函数
{
m2[code.substr(beg,end-beg)]=++funsum;int i=;
for(int next=word(++end);code[next]!=')';end=next+,next=word(end))
if(next-end!= || code.substr(end,)!="int")
par[funsum][++i]=code.substr(end,next-end);
if(code[end]!=')') par[funsum][++i]=code.substr(end,word(end)-end);
end=word(end);
pasum[funsum]=i;
funstart[funsum]=++end;end++;
for(int dep=;dep;end++) if(code[end]=='{') dep++;else if(code[end]=='}') dep--;
return end;
}
int newvar(int beg)//定义新变量
{
int end;
for(end=beg;code[end]!=';';beg=end+)
{
end=word(beg),m1[dep][code.substr(beg,end-beg)]=varsum[dep];
int from=varsum[dep];weisum[varsum[dep]]=;
for(varsum[dep]+=getsize(end,varsum[dep]);from<=varsum[dep];from++) var[from]=;
}
return end+;
}
void newdep()//新的一层
{
varsum[dep+]=varsum[dep];m1[dep+]=m1[dep];dep++;
}
int calc(int &now)//表达式求值
{
int run(int now,bool isfun);
int fh[],st[];bool isvar[];int top=,pre[],presum=;
for(;code[now]!=';' && code[now]!=')' &&(code[now]!='<' || code[now+]!='<')&&(code[now]!=']')&&(code[now]!=',');)
if(s3.count(code[now]))
{
st[++top]=num(now);
while(presum>)
{
if(pre[presum]==) st[top]=!st[top];
if(pre[presum]==) st[top]=-st[top];
presum--;
}
isvar[top]=;fh[top]=-;
}
else
if(s1.count(code[now]))
if(m1[dep].count(code.substr(now,word(now)-now)))
{
int next=word(now),first=m1[dep][code.substr(now,word(now)-now)];
st[++top]=first+focus(next,first);isvar[top]=;
while(presum>)
{
st[top]=st(top);isvar[top]=;
if(pre[presum]==) st[top]=!st[top];
if(pre[presum]==) st[top]=-st[top];
presum--;
}
fh[top]=-;now=next;
}
else
{
int End=word(now),all=,end=End+,patem[];
while(code[end]!=')')
patem[++all]=calc(end),end+=code[end]==',';
PA=m2[code.substr(now,End-now)];retu=;
for(int i=;i<=all;i++)
pa[i]=patem[i];
run(funstart[PA],);
st[++top]=retu;fh[top]=-;isvar[top]=;
while(presum>)
{
if(pre[presum]==) st[top]=!st[top];
if(pre[presum]==) st[top]=-st[top];
presum--;
}
now=end+;
}
else
if(code[now]=='(')
{
now++;
st[++top]=calc(now);
while(presum>)
{
if(pre[presum]==) st[top]=!st[top];
if(pre[presum]==) st[top]=-st[top];
presum--;
}
isvar[top]=;fh[top]=-;now++;
}
else
if(!top || fh[top]!=-)
while(code[now]=='!' || code[now]=='-' || code[now]=='+')
switch(code[now])
{
case'!':pre[++presum]=;now++;break;
case'-':pre[++presum]=;now++;break;
case'+':now++;break;
}
else
{
int newlevel=level(now);
while(top> && dayu(fh[top-],newlevel))
switch(fh[--top])
{
case :var[st[top]]=st(top+);st[top]=st(top+);isvar[top]=;break;
case :st[top]=st(top)||st(top+);isvar[top]=;break;
case :st[top]=st(top)&&st(top+);isvar[top]=;break;
case :st[top]=st(top)^st(top+);isvar[top]=;break;
case :st[top]=st(top)==st(top+);isvar[top]=;break;
case :st[top]=st(top)!=st(top+);isvar[top]=;break;
case :st[top]=st(top)<=st(top+);isvar[top]=;break;
case :st[top]=st(top)>=st(top+);isvar[top]=;break;
case :st[top]=st(top)<st(top+);isvar[top]=;break;
case :st[top]=st(top)>st(top+);isvar[top]=;break;
case :st[top]=st(top)+st(top+);isvar[top]=;break;
case :st[top]=st(top)-st(top+);isvar[top]=;break;
case :st[top]=st(top)*st(top+);isvar[top]=;break;
case :st[top]=st(top)/st(top+);isvar[top]=;break;
case :st[top]=st(top)%st(top+);isvar[top]=;break;
}
fh[top]=newlevel;now++;
}
for(top--;top>;top--)
switch(fh[top])
{
case :var[st[top]]=st(top+);st[top]=st(top+);isvar[top]=;break;
case :st[top]=st(top)||st(top+);isvar[top]=;break;
case :st[top]=st(top)&&st(top+);isvar[top]=;break;
case :st[top]=st(top)^st(top+);isvar[top]=;break;
case :st[top]=st(top)==st(top+);isvar[top]=;break;
case :st[top]=st(top)!=st(top+);isvar[top]=;break;
case :st[top]=st(top)<=st(top+);isvar[top]=;break;
case :st[top]=st(top)>=st(top+);isvar[top]=;break;
case :st[top]=st(top)<st(top+);isvar[top]=;break;
case :st[top]=st(top)>st(top+);isvar[top]=;break;
case :st[top]=st(top)+st(top+);isvar[top]=;break;
case :st[top]=st(top)-st(top+);isvar[top]=;break;
case :st[top]=st(top)*st(top+);isvar[top]=;break;
case :st[top]=st(top)/st(top+);isvar[top]=;break;
case :st[top]=st(top)%st(top+);isvar[top]=;break;
}
if(code[now]==';')
now++;
return st();
}
int sentence(int now)//执行语句
{
int run(int now,bool isfun);
int next=word(now);
if(code[now]=='{')
next=run(now,);
else
if(next-now== && code.substr(now,)=="if")
{
newdep();
next++;
int end=express(next);
if(calc(next))
{
next++;next=sentence(next);
int end=word(next);
if(end-next== && code.substr(next,)=="else")
next=block(end);
}
else
{
next++;
next=block(next);
int end=word(next);
if(end-next== && code.substr(next,)=="else")
next=sentence(end+(code[end]==' '));
}
dep--;
}
else
if(next-now== && code.substr(now,)=="for")
{
newdep();
int judge;
judge=(code[next+]==';')?next+:sentence(next+);int ju=judge;
if(RETU) return next;
int done=express(judge)+;
int blo=done,deep=;
while(deep)
{
if(code[blo]=='(') deep++;
if(code[blo]==')') deep--;
blo++;
}
while((code[ju]==';')?:calc(ju))
{
ju=judge,sentence(blo);
if(RETU) return next;
sentence(done);
if(RETU) return next;
}
next=block(blo);
dep--;
}
else
if(next-now== && code.substr(now,)=="while")
{
newdep();
int judge=next+,ju=judge;
if(RETU) return next;
int blo=judge,deep=;
while(deep)
{
if(code[blo]=='(') deep++;
if(code[blo]==')') deep--;
blo++;
}
while(calc(ju))
{
sentence(blo),ju=judge;
if(RETU) return next;
}
next=block(blo);
dep--;
}
else
if(next-now== && code.substr(now,)=="cin")
{
int qian=next,hou=next+;
while(code[qian]!=';')
{
qian=word(hou+);
int first=m1[dep][code.substr(hou+,qian-hou-)];
var[first+focus(qian,first)]=input[++read];
hou=qian+;
}
next=hou;
}
else
if(next-now== && code.substr(now,)=="cout")
{
int qian=next,hou=next+;
while(code[qian]!=';')
{
qian=hou+;
while((code[qian]!='<' || code[qian+]!='<' )&&(code[qian]!=';')) qian++;
if(qian-hou== && code.substr(hou+,)=="endl")
puts("");
else
hou++,printf("%d",calc(hou));
hou=qian+;
}
next=hou;
}
else
if(next-now== && code.substr(now,)=="putchar")
next++,printf("%c",calc(next)),next+=;
else
if(next-now== && code.substr(now,)=="int")
next=newvar(next+);
else
if(next-now== && code.substr(now,)=="return")
next++,retu=calc(next),RETU=;
else
{
calc(now);
next=now;
}
return next;
}
int run(int now,bool isfun)//从某个{开始运行
{
newdep();now++;
if(PA)
for(int i=;i<=pasum[PA];i++)
m1[dep][par[PA][i]]=varsum[dep],var[varsum[dep]]=pa[i],varsum[dep]++;
PA=;
for(int next=now;code[next]!='}'&& !RETU;now=next)
next=sentence(now);
dep--;if(isfun)RETU=;now++;
return now;
}
int main()
{
init();
for(int i=,j;i<len;i=j)//处理全局变量和函数
{
i=word(i)+;j=word(i);//过滤int
if(code[j]=='(') j=newfun(i,j);
else j=newvar(i);
}
run(funstart[m2["main"]],);
return ;
}
也不是很长啊\(^o^)/~
uoj98未来程序改 纯暴力不要想了的更多相关文章
- 如何A掉未来程序改
话说有这样一道神题:[集训队互测2015]未来程序·改. 大意是要求写一个简单的C++解释器!这里去掉了C++的许多特性,连简单的break和continue都没有了! 话说NOI被屠了之后,一时心血 ...
- bzoj4020: 未来程序·改
只需写一个解释器 第一次预处理将输入进行分词,分割出 关键字,运算符,变量/函数名,整数常量,并对变量/函数名离散化以便处理 第二次预处理建语法树,每个节点存节点类型,变量定义表等信息 运行时在语法树 ...
- uoj#73 【WC2015】未来程序
在 2047 年,第 64 届全国青少年信息学奥林匹克冬令营前夕,B君找到了 2015 年,第 32 届冬令营的题目来练习. 他打开了第三题 “未来程序” 这道题目: 本题是一道提交答案题,一共 10 ...
- Uoj 73 未来程序
Uoj 73 未来程序 神仙提答. Subtask 1 仔细阅读,发现是要计算 \(a*b\ \%\ c\).用龟速乘或者 \(python\) 直接算. Subtask 2 仔细阅读并手算一下,发现 ...
- 2019 Multi-University Training Contest 6 Nonsense Time (纯暴力)
题意:给你一个n的排列,起初这些数都不能用, 然后还有一个数组 第 i 个数表示下标为 i 的数能够使用. 问每一个 i 对应的最长上升子序列. 题解: 可以通过倒推,从后往前考虑转化一下 ,然后就是 ...
- 问题-某个程序改了ICO图标后编译后还是显示老图标?
问题现象:某个程序改了ICO图标后编译后还是显示老图标? 问题原原:可能是因为系统的缓存问题. 问题处理:把程序的EXE放在别的路径下打开就可以了. 问题相关人员:QQ253120114(朋友) Q ...
- 好程序员web前端分享想要学习前端需要学那些课程
好程序员web前端分享想要学习前端需要学那些课程,仔细思考了一下如何回答好这个话题,其实前端是一个涵盖面非常之广泛的一个职位,所需知识体系非常庞杂,与传统语言“想要精一行,必先通一门” 有很大差别, ...
- 2: 使用Prism初始化程序(纯汉语版)
本篇内容讲解了Prism应用程序启动和运行都发生了什么.一个Pris应用程序在程序启动期间需要注册和配置——这被叫做引导应用程序.Prism引导过程包括创建和配置一个模块目录,创建一个例如Unity的 ...
- 作为程序员,再也不想和PM干架了
上周,又看见有程序和PM(产品经理)吵了起来,大致是因为晚上就要上线了,下午的时候PM来说要改点需求,但程序不愿意.兴许是天气热了,大家都很烦躁,于是一言不合就发飙了,最终还是程序老大介入才解决了问题 ...
随机推荐
- 如何做出透明背景的flash动画
最近碰到了一个问题,做动画时怎么设置透明背景,字是白色的,网上搜了一下,发现可以这样做 在插入的flash代码中加入这一行代码就可以实现了 <param name="wmode&quo ...
- Android实现双击事件的两种方式
Work around的方法是先监听onTouch事件来监听连续点击次数,每次点击都布置一个间隔时间的延时任务,延时任务执行时判断间隔内是否还有点击,如果没有则发布点击次数,重置计数. 实现代码如下: ...
- echarts饼图
1.添加点击事件并跳转到不同的页面 // 路径配置 require.config({ paths: { echarts: 'http://echarts.baidu.com/build/dist/' ...
- PHPSTORM设置新建PHP文件头部注释
1.选择 File|setting 2.在Editor|File and Code Templates,见下图标记更改即可
- xamarin android webview XHR错误
Cross origin requests are only supported for protocol schemes MLHttpRequest cannot load file:///F:/G ...
- 查看sqlserver被锁的表以及如何解锁
select request_session_id spid,OBJECT_NAME(resource_associated_entity_id) tableName from sys.dm_tran ...
- 3.1 AngularJS必备知识
AngularJS是一个WEB应用框架. 本节我们会学习控制器(控制数据),会学习作用域(连接控制器和用户界面),用户界面又叫做视图,通过模板和作用域来创建交互视觉效果.另外,我们还会学习其他的特性比 ...
- 【JavaScript】ES6 新语法
function* 声明 function* 声明(function关键字后跟一个星号)定义一个generator(生成器)函数,返回一个Generator对象. 生成器是一种可以从中退出并在之后重新 ...
- 【DWR系列04】- DWR配置详解
table { margin-left: 30px; width: 90%; border: 1px; border-collapse: collapse } img { border: 1px so ...
- SQL语句实现Split并合并查询结果
需求是这样的,需要将数据库中的支付方式列(用";"分割的字符串)按支付方式拆分: 首先参考博客园split的文章,我采用方法2, IF EXISTS ( SELECT * FROM ...