CSU 1378 Shipura 简单模拟
2024-08-28 13:21:30
上周末中南的题,当时就知道是个简单模拟题,可是一个多小时就是没写出来,代码能力啊 >.<
题意:
某人发明了一种程序语言,只支持一种运算">>",和一种函数"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;
}
最新文章
- C#操作字符串方法总结<;转>;
- 【转】从RGB色转为灰度色算法
- Training little cats_矩阵快速幂
- Nginx配置:http重定向,URLRewrite,一个简单框架的配置思路
- org.apache.hadoop.fs-Seekable
- SQL常用分页
- Java常用代码段 - 未完待续
- 数据库文件导入导出操作,以及赋予权限SQL语句
- tempnam问题
- sqlplus入门使用
- Java Native Interface调用C++代码
- LeetCode刷题(Java)
- 【图解】Hive文件存储格式
- linux之目录知识
- oracle11g的监听配置文件中的program和env两个配置,必须干掉,客户端才能正常连接
- PythonStudy——字符串扩展方法 String extension method
- Windows10 家庭版 Docker的安装
- Linux 下配置 Git 操作免登录 ssh 公钥
- iframe解决ajax主域和子域之间的跨域问题
- 修改.net反编译的dll
热门文章
- 再次建立wordpress
- (转载)ExpandableListView 安卓二级菜单
- HTML&;CSS——网站注册页面
- DotNetCore.1.0.1-VS2015Tools.Preview2.0.2 安装错误分析及解决办法(so far)
- JDOM,dom4j方式解析XML
- NodeJS学习笔记 (4)网络服务-http(ok)
- CF504E Misha and LCP on Tree(树链剖分+后缀树组)
- luogu P4139 上帝与集合的正确用法(扩展欧拉定理)
- 魔兽争霸RPG游戏-军团战争-游戏经验总结
- BNUOJ 36005 Chemical Reaction