上周末中南的题,当时就知道是个简单模拟题,可是一个多小时就是没写出来,代码能力啊 >.<

题意:

  某人发明了一种程序语言,只支持一种运算">>",和一种函数"S<>"。现在给你一个表达式,让你求值。 表达式有以下几种元素:

expr : term 或者 expr+sp+">>"+sp+term

term : number 或者 "S"+sp+"<"+sp+expr+sp+">"

sp : "" 或者 " "

number : digit 或者 number+digeit

digit : "0" 或者 "1" 或者 "2" 或者 "3" 或者 "4" 或者 "5" 或者 "6" 或者 "7" 或者 "8" 或者 "9"

给你的表达式一定是一个expr,并且number总是 0到1,000,000,000之间的数。

思路:

  这实际上就是一个计算器,只有两种运算: ">>" 这个事实上就是C语言里面的右位移,不过要注意的是,当移动的位数太大时,结果可能会向下溢出,因此要特判一下。
 另外"S<>" 可以看成一种单目运算。

  因为是计算器嘛,理所应当的想到用栈来做。 两个栈,一个存放运算数,另一个存放运算符。当遇到"S"或者">>"运算的时候,直接入栈,当遇到数字的时候,先检查栈顶是否为>>运算,如果是,则从数字栈里面再弹出一个数来运算,否则入栈。 当遇到"S<>"中的">"时, 从数字栈中弹出一个数字进行运算。

  如何区分 ">>"和 “>” 根据">>"后面一定会跟着数字,或者类似数字的东西。

  另外,我先把所有的空格去掉了,觉得这样更好判断符号。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack> using namespace std; typedef long long ll; const ll MOD = (ll)1e9+7;
const int MAXN = (int)2e6+9; stack<ll> num;
stack<char> op; char str[MAXN];
char str2[MAXN]; inline ll S(ll x) {
return (x*x)%MOD;
} void pushNum(ll x) {
while (!op.empty() && '^'==op.top()) { //其实这个用if就好了,因为>>运算时先计算左边,所以栈中不会出现连续的>>运算
op.pop();
ll tmp = num.top(); num.pop();
if (x>60) {
tmp = 0;
x = 0;
}
x = (tmp>>x);
}
num.push(x);
} void slove() {
int i = 0;
ll tmp;
while (true) {
if ('\0'==str[i]) break; while (' '==str[i]) i++; if ('S'==str[i]) {
op.push('S');
i++;
continue;
}
if ('<'==str[i]) {
i++;
continue;
}
if ('0'<=str[i]&&str[i]<='9') {
tmp = 0;
while ('0'<=str[i]&&str[i]<='9') {
tmp *=10;
tmp += str[i]-'0';
i++;
}
pushNum(tmp);
continue;
}
if ('>'==str[i]) {
if ('>'==str[i+1] && ('S'==str[i+2] || ('0'<=str[i+2]&&str[i+2]<='9'))) {
op.push('^');
i++;
}else if ('S'==op.top()) {
op.pop();
tmp = num.top(); num.pop();
pushNum(S(tmp));
}
i++;
continue;
}
}
printf("%lld\n", num.top());
} void Transform(){
int i = 0, j = 0;
while (true) {
if ('\0'==str2[i]) break;
if (' '==str2[i]) while (' '==str2[i]) i++;
else {
str[j++] = str2[i++];
}
}
str[j] = '\0';
} int main()
{
#ifdef Phantom01
freopen("CSU1378.txt", "r", stdin);
#endif // Phantom01 while (gets(str2)) {
if ('#'==str2[0]&&'\0'==str2[1]) break; while (!num.empty()) num.pop();
while (!op.empty()) op.pop(); Transform();
slove();
} return 0;
}

最新文章

  1. C#操作字符串方法总结&lt;转&gt;
  2. 【转】从RGB色转为灰度色算法
  3. Training little cats_矩阵快速幂
  4. Nginx配置:http重定向,URLRewrite,一个简单框架的配置思路
  5. org.apache.hadoop.fs-Seekable
  6. SQL常用分页
  7. Java常用代码段 - 未完待续
  8. 数据库文件导入导出操作,以及赋予权限SQL语句
  9. tempnam问题
  10. sqlplus入门使用
  11. Java Native Interface调用C++代码
  12. LeetCode刷题(Java)
  13. 【图解】Hive文件存储格式
  14. linux之目录知识
  15. oracle11g的监听配置文件中的program和env两个配置,必须干掉,客户端才能正常连接
  16. PythonStudy——字符串扩展方法 String extension method
  17. Windows10 家庭版 Docker的安装
  18. Linux 下配置 Git 操作免登录 ssh 公钥
  19. iframe解决ajax主域和子域之间的跨域问题
  20. 修改.net反编译的dll

热门文章

  1. 再次建立wordpress
  2. (转载)ExpandableListView 安卓二级菜单
  3. HTML&amp;CSS——网站注册页面
  4. DotNetCore.1.0.1-VS2015Tools.Preview2.0.2 安装错误分析及解决办法(so far)
  5. JDOM,dom4j方式解析XML
  6. NodeJS学习笔记 (4)网络服务-http(ok)
  7. CF504E Misha and LCP on Tree(树链剖分+后缀树组)
  8. luogu P4139 上帝与集合的正确用法(扩展欧拉定理)
  9. 魔兽争霸RPG游戏-军团战争-游戏经验总结
  10. BNUOJ 36005 Chemical Reaction