写在前面

实际上已近写过一篇这个题的题解了,这次只是稍作修改,压缩了以前又臭又长的代码,顺便再说明一下解题思路。

遇到的问题

一看这个题就知道是模拟,但是怎么模拟呢?

首先,读入与存储问题,如何准确的读入以及如何将输入的代码存起来。

其次,也是最难的,模拟程序运行,其中最关键的就是如何模拟循环的运行。

再者,计算器的问题,赋值语句与循环次数的计算。

解决方案

1.读入与存储,开一个二维的char数组(string也行,个人喜好),使用scanf("%s",s)读入,遇到空格跳过。

2.运行过程,其他语句不多说,就讲讲最关键的循环语句吧,看到有很多大佬都是用栈来模拟,个人不太习惯用栈模拟,于是用了类似于递归的方法,一层层进入,再退出。

3.有关计算器,由于题中给出了语句的执行次数的总和小于2000000次,那么计算器完全可以使用递归代替栈来写,并且完全不用担心会超时。

最后附上AC代码,代码中有解释

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#define MAXN 1001
using namespace std;//函数总览,后面有解释
void read();
void work();
void find();
void write(char x[]);
int check(char x[]);
void run(char x[]);
void pre(char x[],int l,int r);
int calc(char x[],int l,int r);
void run_loo(char x[]);
int run_fu(char x[],int in,int enk);char str[MAXN][MAXN],s[MAXN];
int sumword=0,h=1,f[MAXN],ff[MAXN],sh[30];
const int sta=1,en=2,loo=3,con=4,wri=5,bre=6,fu=7;//读入,处理掉空格
void read(){while((scanf("%s",s))!=EOF){if(s[0]!=' '){strcpy(str[++sumword],s);}}
}//输出
void run_wri(char x[]){++h;printf("%d\n",run_fu(str[h],0,strlen(str[h])-1));
}//预处理,找到循环的开始与结束
void find(){int v[MAXN],v1=0;for(int i=2;i<sumword;i++){if(check(str[i])==loo){v1++;v[v1]=i;}else if(check(str[i])==en){f[v[v1]]=i;v1--;}}
}//循环语句的递归实现
void run_loo(char x[]){++h;int t=run_fu(str[h],0,strlen(str[h])-1),tmp=h-1;for(int i=1;i<=t;i++){++h;while(check(str[h])!=en){if(check(str[h])==loo){run_loo(x);}else if(check(str[h])==con){break;}else if(check(str[h])==bre){h=f[tmp];return;}run(str[h]);++h;}h=tmp+1;}h=f[tmp];
}//每次使用计算器之前的预处理,为了处理表达式中有括号匹配的情况
void pre(char x[],int l,int r){int v[MAXN],sumword=0;for(int i=l;i<=r;++i){if(x[i]=='('){v[++sumword]=i;}else if(x[i]==')'){ff[v[sumword]]=i;--sumword;}}
}//递归实现简单计算器
int calc(char x[],int l,int r){if(l==r&&x[l]>='a'&&x[l]<='z') return sh[x[l]-'a'];if(x[l]=='('&&x[r]==')'&&ff[l]==r){return calc(x,l+1,r-1);}int jia=0,cheng=0,isjia=0,ischeng=0,fa=0,isfa=0;for(int i=l;i<=r;++i){if(x[i]=='+') jia=i,isjia=1;else if(x[i]=='*') cheng=i,ischeng=1;else if(x[i]=='/') cheng=i,ischeng=0;else if(x[i]=='-') jia=i,isjia=0;else if(x[i]=='^') isfa=1,fa=i;else if(x[i]=='(') i=ff[i]-1;}if(jia!=0){if(isjia==1) return (calc(x,l,jia-1)+calc(x,jia+1,r));else return (calc(x,l,jia-1)-calc(x,jia+1,r));}else if(cheng!=0){if(ischeng==1) return (calc(x,l,cheng-1)*calc(x,cheng+1,r));else return (calc(x,l,cheng-1)/calc(x,cheng+1,r));}else if(isfa!=0){return (int)pow(calc(x,l,fa-1)*1.0,calc(x,fa+1,r)*1.0);}else if(jia==0&&cheng==0&&isfa==0){int tmp=0;for(int i=l;i<=r;++i){tmp=(tmp*10+(x[i]-'0'));}return tmp;}
}//赋值语句的运行,调用calc()函数计算
int run_fu(char x[],int in,int enk){memset(ff,0,sizeof(ff));pre(x,in,enk);int res=calc(x,in,enk);return res;
}//判断是哪一种语句
int check(char x[]){if(x[1]=='='){return fu;}else if(x[0]=='s'){return sta;}else if(x[0]=='e'&&x[1]=='n'){return en;}else if(x[0]=='l'&&x[1]=='o'){return loo;}else if(x[0]=='c'&&x[1]=='o'){return con;}else if(x[0]=='w'&&x[1]=='r'){return wri;}else if(x[0]=='b'&&x[1]=='r'){return bre;}else{return -1;}
}//运行每一句语句
void run(char x[]){int k=check(x);switch(k){case 3:run_loo(x); break;case 5:run_wri(x); break;case 7:sh[x[0]-'a']=run_fu(x,2,strlen(x)-1); break;default:break;}
}//循环每一句语句
void work(){while(h<=sumword){run(str[h]);++h;}
}int main(){ read();find();work();return 0;
}

有问题可在评论区留言哟。(●'◡'●)。~~~~~~~

[HNOI2002] 沙漠寻宝题解相关推荐

  1. [NOIP2012 普及组] 寻宝题解

    题目 题目描述 传说很遥远的藏宝楼顶层藏着诱人的宝藏.小明历尽千辛万苦终于找到传说中的这个藏宝楼,藏宝楼的门口竖着一个木板,上面写有几个大字:寻宝说明书.说明书的内容如下: 藏宝楼共有 N + 1 N ...

  2. CSP 202206 题解:归一化处理,寻宝大冒险,角色授权,光线追踪,PS无限版

    试题内容请前往CCF官网查看: CCF-CSP计算机软件能力认证考试 http://118.190.20.162/home.page 阅读本题解前,您应当了解下列知识: 线段树 教程 C++ 标准库( ...

  3. CCF- CSP 202206-2寻宝!大冒险!暴力算法满分题解

    CCF- CSP 202206-2寻宝!大冒险!暴力算法满分题解 题目链接:202206-2寻宝!大冒险! 思路: 数据范围中n ≤ \leq ≤ 1000,S ≤ \leq ≤ 50,考虑时间复杂度 ...

  4. CCF CSP认证202206-02 寻宝!大冒险!C++题解

    题目: 分析 通俗点说,我们需要解决的问题,就是计算小地图(藏宝图)能正好对上大地图(绿化图)的次数,需要保证两个条件:1)小地图必须包含在大地图中,2)0和1必须完全对应 70分解法:暴力搜索大地图 ...

  5. bzoj1588[HNOI2002]营业额统计

    bzoj1588[HNOI2002]营业额统计 题意: n天,每天得到一个值,要求输出每一天和这天得到的值相差最小的之前天得到的值与这个值的差的和.n不知道,不过O(nlog2n)可写. 题解: 说是 ...

  6. 【链表】BZOJ1588: [HNOI2002]营业额统计

    1588: [HNOI2002]营业额统计 Time Limit: 5 Sec  Memory Limit: 162 MB Submit: 17555  Solved: 7179 [Submit][S ...

  7. Rabbit寻宝记(1)

    Description Rabbit 为了寻宝来到了一个神秘森林,但是她却发现森林唯一入口的大门被锁上了. 大门上写着一个奇怪的字符串.字符串只由大写字母,小写字母,数字组成,且至少有一个非数字字符. ...

  8. 信息学奥赛一本通 1958:【12NOIP普及组】寻宝 | OpenJudge NOI 1.12 06 | 洛谷 P1076 [NOIP2012 普及组] 寻宝

    [题目链接] ybt 1958:[12NOIP普及组]寻宝 洛谷 P1076 [NOIP2012 普及组] 寻宝 OpenJudge NOI 1.12 06:寻宝 [题目考点] 1. 模拟 2. 循环 ...

  9. 字节跳动杯2018中国大学生程序设计竞赛-女生专场题解

    以下所有AC题解程序来自"仙客传奇"团队. A. 口算训练 题解链接: ABDFHK "字节跳动杯"2018中国大学生程序设计竞赛-女生专场 B. 缺失的数据范 ...

最新文章

  1. 图像拼接--Coarse-to-fine Seam Estimation for Image Stitching
  2. RIPv2 路由手工汇总
  3. 数据中心成投资新宠 今年或再创历史纪录
  4. python自动化测试面试题代码_Python自动化测试常见面试题(四)
  5. SecureCRT登陆Centos 6.4乱码问题
  6. AcWing 876. 快速幂求逆元
  7. php调用文章至首页,WP如何在首页调用分类文章列表的详细教程
  8. python模拟栈的操作实现非递归方式的快速排序算法
  9. CCNA学习指南 TCP/IP
  10. 业务层——跨越边界传输数据
  11. win7添加java环境变量path_Win7怎么配置Java环境变量?
  12. 网页端下载喜马拉雅音频
  13. UML软件开发与建模工具Enterprise Architect发布最新版本v15.2
  14. ubuntu linux 教程 pdf,Ubuntu 12.04 菜鸟完全使用教程(四) PDF
  15. CKEditor 简介
  16. pytorch并行处理详解(多GPU,环境变量)
  17. 如何两个电脑共享文件实现多人编辑_怎么才能几台电脑同时编辑共享的同一word文档...
  18. 面试ppt计算机自我介绍,面试中技巧及怎样自我介绍.ppt
  19. wordpress mysql 5.7_CentOS7 运维 - 搭建WordPress论坛 | 超详细 | MySQL安装使用
  20. AFL白皮书实现细节

热门文章

  1. 递归专题---[2]开根号
  2. 测试Java测试Java测试Java
  3. 虚幻引擎学习之路:动画模块之基础篇
  4. 在线Java 动态运行Java源代码-执行器
  5. 在线运行java测试
  6. 思科ccie和华为hcie中交换机环路的产生原因和解决方法
  7. 辞旧迎新,继往开来:2021→2022
  8. 怎么在中国使用chatgpt
  9. 图片处理-指定大小缩放
  10. 一个大二学生从屌丝开始的逆袭