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来说要改点需求,但程序不愿意.兴许是天气热了,大家都很烦躁,于是一言不合就发飙了,最终还是程序老大介入才解决了问题 ...
随机推荐
- python之路十六
一.什么是DOM? 什么叫DOM,DOM是文档对象模型(Document Object Model,是基于浏览器编程(在本教程中,可以说就是DHTML编程)的一套API接口,W3C出台的推荐标准 ...
- css-关于位置
当你设置一个你想要相对的模块为relative 你这个模块为absolute 则你的这个absolute会相对relative的那个模块进行移动.
- Bootstrap.css 中请求googleapis.com/css?family 备忘录
问题描述: Web中引入bootstrap.css中头部有访问Google服务器的请求 @import url("//fonts.googleapis.com/css?family=Open ...
- NetBeans建立跳过测试构建的快捷方式
在项目浏览器中右键项目->属性,如图进行设置: 此后按下图即可运行自定义行为:
- 编译器--__attribute__ ((packed))
1. __attribute__ ((packed)) 的作用就是告诉编译器取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐,是GCC特有的语法.这个功能是跟操作系统没关系,跟编译器有关,g ...
- ftp org.apache.commons.net.ftp.FTPClient 判断文件是否存在
String path = "/SJPT/ONPUT/HMD_TEST/" ; FtpTool.getFTPClient().changeWorkingDirectory(path ...
- (转)java redis使用之利用jedis实现redis消息队列
应用场景 最近在公司做项目,需要对聊天内容进行存储,考虑到数据库查询的IO连接数高.连接频繁的因素,决定利用缓存做. 从网上了解到redis可以对所有的内容进行二进制的存储,而java是可以对所有对象 ...
- 关于for循环------swift3.0
在程序开发当中,for循环使用的频率无疑是最高的.常用的swift循环是递增式遍历.当然各种循环,swift都能办到.但其大多采用关键字形式实现,大部分开发者更喜欢直接使用C式循环代码.在swift3 ...
- R3.2.2安装
- ****LINUX命令(含GIT命令)个人总结
参考文章: 每日一个linux命令 http://www.cnblogs.com/peida/tag/%E6%AF%8F%E6%97%A5%E4%B8%80linux%E5%91%BD%E4%BB%A ...