文章目录
- [NOIP2013 普及组] 表达式求值
- 题目描述
- 输入格式
- 输出格式
- 样例 #1
- 样例输入 #1
- 样例输出 #1
- 样例 #2
- 样例输入 #2
- 样例输出 #2
- 样例 #3
- 样例输入 #3
- 样例输出 #3
- 提示
- 题意解析
- 思路解析
- CODE
- 注意
[NOIP2013 普及组] 表达式求值
题目链接:https://www.luogu.com.cn/problem/P1981
题目描述
给定一个只包含加法和乘法的算术表达式,请你编程计算表达式的值。
输入格式
一行,为需要你计算的表达式,表达式中只包含数字、加法运算符 “ + + +” 和乘法运算符 “$ \times $”,且没有括号,所有参与运算的数字均为 0 0 0 到 2 31 − 1 2^{31}-1 231−1 之间的整数。
输入数据保证这一行只有 $ 0\sim 9 、 、 、+ 、 、 、 \times $ 这 $12 $种字符。
输出格式
一个整数,表示这个表达式的值。
注意:当答案长度多于 4 4 4 位时,请只输出最后 $ 4$ 位,前导 $ 0$ 不输出。
样例 #1
样例输入 #1
1+1*3+4
样例输出 #1
8
样例 #2
样例输入 #2
1+1234567890*1
样例输出 #2
7891
样例 #3
样例输入 #3
1+1000000003*1
样例输出 #3
4
提示
对于 30 % 30\% 30% 的数据, 0 ≤ 0≤ 0≤ 表达式中加法运算符和乘法运算符的总数 ≤ 100 ≤100 ≤100。
对于 80 % 80\% 80% 的数据, 0 ≤ 0≤ 0≤ 表达式中加法运算符和乘法运算符的总数 ≤ 1000 ≤1000 ≤1000。
对于 100 % 100\% 100% 的数据, 0 ≤ 0≤ 0≤ 表达式中加法运算符和乘法运算符的总数 ≤ 100000 ≤100000 ≤100000。
题意解析
给你一个只有'+'
和'*'
的式子,求结果,数据范围在 i n t int int 之内。
思路解析
- 直接读入整个式子,然后往后遍历,如果是数字就累加,如果遇到符号,进行不同操作
- 如果读入了
'+'
:将之前累加的数压入栈,然后对用于累加数字的变量n
清零 - 如果读入了
'*'
:将之前累加的数压入栈,然后对n
清零,然后再用双指针读入下一个数,弹栈得到上一个数,将乘法结果算出来后再压入栈内。
我的思路很明了,反正除了乘法就是加法,而乘法优先级更高,那么就在遇到加法的时候不运算只压栈,遇到乘法的时候把值算出来压入栈,最后再加在一起即可。
CODE
#include <iostream>
#include <cstring>
#include <algorithm>
#define ll long long // 本题用int完全够用,不用ll类型using namespace std;const int N = 1e8 + 10, mod = 10000;
ll n, stk[N], tt = -1;
string s;int main(){cin >> s; // 读入整个表达式 ll l = s.size(); // 长度 for(ll i = 0; i < l; ++i){ // 从头遍历到尾 if(s[i] >= '0' && s[i] <= '9') n = n * 10 + (s[i] - '0'); //如果是数字进行累记 else if(s[i] == '+'){ // 如果是加法,把之前累计的数字压栈 if(n != 0){stk[++tt] = n % mod;n = 0;}}else{ // 如果是乘法,将之前累计的数字压栈 if(n != 0){stk[++tt] = n % mod;n = 0;}++i;while(s[i] >= '0' && s[i] <= '9'){ // 读入下一个数字 n = n * 10 + (s[i] - '0');++i;}--i; // 指针回退一个 stk[++tt] = n % mod; // 压栈 n = 0;ll a = stk[tt--]; // 取出两个数字相乘,得到的结果压栈保存 ll b = stk[tt--];a = a * b;stk[++tt] = a % mod;}}stk[++tt] = n % mod; // 如果最后一个符号是+,则余下一个数字,压栈 ll ans = 0;while(tt >= 0){ // 将栈内数字全部累加得到答案 ans = (ans + stk[tt--]) % mod; }cout << ans;
}
注意
- 每次遇到符号压入之前累计的数字时,需要判断是否为 0 0 0,尤其是在乘法时,因为会有连乘的存在,我们在运算完第一个乘法时,累计数字
n
会被清零,此时我们不能再对它压栈,否则连乘的答案将被乘上 0 0 0 最终错误。
本题很像之前那个表达式求值啊,不过那个更复杂 <_>。