NC16539 [NOIP2013]表达式求值

题目

题目描述

给定一个只包含加法和乘法的算术表达式,请你编程计算表达式的值。

输入描述

输入仅有一行,为需要你计算的表达式,表达式中只包含数字、加法运算符“+”和乘法运算符“*”,且没有括号。

所有参与运算的数字均为 \(0\) 到 \(2^{31}-1\) 之间的整数。

输入数据保证这一行只有 \(0\) ~ \(9\) 、+ 、*这12种字符。

输出描述

输出只有一行,包含一个整数,表示这个表达式的值。注意:当答案长度多于 \(4\) 位时,请只输出最后 \(4\) 位,前导 \(0\) 不输出。

示例1

输入

1+1*3+4

输出

8

说明

计算的结果为 \(8\) ,直接输出 \(8\) 。

示例2

输入

1+1234567890*1

输出

7891

说明

计算的结果为 \(1234567891\) ,输出后 \(4\) 位,即 \(7891\) 。

示例3

输入

1+1000000003*1

输出

4

说明

计算的结果为 \(1000000004\) ,输出后 \(4\) 位,即 \(4\) 。

备注

对于 \(30\%\) 的数据, \(0\) ≤表达式中加法运算符和乘法运算符的总数≤ \(100\) ;

对于 \(80\%\) 的数据, \(0\) ≤表达式中加法运算符和乘法运算符的总数≤ \(1000\) ;

对于 \(100\%\) 的数据,\(0\) ≤表达式中加法运算符和乘法运算符的总数≤ \(100000\) 。

题解

思路

方法一

知识点:分治。

表达式的运算有优先级直接读取难以计算,但运算总有最后一步,通过找到最后一次的运算将表达式以这个符号拆成左右两部分,就可以展开递归进行相同的操作。每次只需要遍历一遍当前表达式,找到所有符号最后出现的位置,加号优先判断,如果加号没有位置那就看乘号,来决定下一次拆分,如果都没有的话那说明是个纯数字,就字符串转换数字即可。注意到结果保留末四位,等价于模 \(10000\),因为加法乘法在模意义下也具有意义。

此解法属于万能解法,可以十分方便处理所有运算符的一系列计算(包括但不限于加,减,乘,除,乘方,阶乘),而且可以通过改进变为可以带括号。平均复杂度 \(O(n\log n)\) ,但如果每次拆分都在最左最右,那么会退化到 \(O(n^2)\) ,而本题有连续加的特殊数据因此在加法处判断后立即break可以优化。但如果是乘法则无法直接break优化,因为无法确定后方是否有更小优先级的运算符,但本题没有连续乘法的数据qwq。

时间复杂度 平均:\(O(nlogn)\) 最差: \(O(n^2)\)

空间复杂度 \(O(n)\)

方法二

知识点:模拟。

发现连续乘法的数字可以连续算出放入临时变量,然后加入最终答案,因为只有加法和乘法。

时间复杂度 \(O(n)\)

空间复杂度 \(O(n)\)

代码

方法一

#include <bits/stdc++.h>

using namespace std;

const int mod = 1e4;

string s;

int StoI(int l, int r) {
int ans = 0;
for (int i = l;i <= r;i++) ans = (10 * ans + s[i] - '0') % mod;
return ans;
} int calc(int l, int r) {
int pos[2] = { -1,-1 };///+,*
for (int i = l;i <= r;i++) {///找到最后一次出现的符号(因为没有括号直接找最后一次的)
if (s[i] == '+') {
pos[0] = i;
break;
}///找到+可以直接退出,避免最差复杂度
else if (s[i] == '*') pos[1] = i;
}
if (!~pos[0] && !~pos[1]) return StoI(l, r);///纯数
else if (~pos[0]) return (calc(l, pos[0] - 1) + calc(pos[0] + 1, r)) % mod;
else if (~pos[1]) return calc(l, pos[1] - 1) * calc(pos[1] + 1, r) % mod;
return 0;///过编译
} int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> s;
cout << calc(0, s.length() - 1) << '\n';
return 0;
}

方法二

#include <bits/stdc++.h>

using namespace std;

const int mod = 1e4;

int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
string s;
cin >> s;
s += '+';///终止最后一段
int ans = 0;
for (int i = 0, tmp = 0, last = 1;i < s.length();i++) {///tmp指一个数字,last指一个乘法数块
if ('0' <= s[i] && s[i] <= '9') tmp = (tmp * 10 + s[i] - '0') % mod;///更新tmp
else if (s[i] == '+') {///把tmp乘进last,更新ans、tmp、last
last = last * tmp % mod;
ans = (ans + last) % mod;
tmp = 0;
last = 1;
}
else if (s[i] == '*') {///把tmp乘进last,更新tmp
last = last * tmp % mod;
tmp = 0;
}
}
cout << ans << '\n';
return 0;
}

NC16539 [NOIP2013]表达式求值的更多相关文章

  1. NOIP2013 表达式求值

    题目描述 Description 给定一个只包含加法和乘法的算术表达式,请你编程计算表达式的值. 输入描述 Input Description 输入仅有一行,为需要你计算的表达式,表达式中只包含数字. ...

  2. NOIP2013普及组 T2 表达式求值

    OJ地址:洛谷P1981 CODEVS 3292 正常写法是用栈 #include<iostream> #include<algorithm> #include<cmat ...

  3. [NOIP2013 普及组] 表达式求值

    [NOIP2013 普及组] 表达式求值 给定一个只包含加法和乘法的算术表达式,请你编程计算表达式的值. Input 一行,为需要你计算的表达式,表达式中只包含数字.加法运算符"+" ...

  4. 表达式求值(noip2015等价表达式)

    题目大意 给一个含字母a的表达式,求n个选项中表达式跟一开始那个等价的有哪些 做法 模拟一个多项式显然难以实现那么我们高兴的找一些素数代入表达式,再随便找一个素数做模表达式求值优先级表 - ( ) + ...

  5. 用Python3实现表达式求值

    一.题目描述 请用 python3 编写一个计算器的控制台程序,支持加减乘除.乘方.括号.小数点,运算符优先级为括号>乘方>乘除>加减,同级别运算按照从左向右的顺序计算. 二.输入描 ...

  6. 数据结构算法C语言实现(八)--- 3.2栈的应用举例:迷宫求解与表达式求值

    一.简介 迷宫求解:类似图的DFS.具体的算法思路可以参考书上的50.51页,不过书上只说了粗略的算法,实现起来还是有很多细节需要注意.大多数只是给了个抽象的名字,甚至参数类型,返回值也没说的很清楚, ...

  7. nyoj305_表达式求值

    表达式求值 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 Dr.Kong设计的机器人卡多掌握了加减法运算以后,最近又学会了一些简单的函数求值,比如,它知道函数min ...

  8. 利用栈实现算术表达式求值(Java语言描述)

    利用栈实现算术表达式求值(Java语言描述) 算术表达式求值是栈的典型应用,自己写栈,实现Java栈算术表达式求值,涉及栈,编译原理方面的知识.声明:部分代码参考自茫茫大海的专栏. 链栈的实现: pa ...

  9. 数据结构--栈的应用(表达式求值 nyoj 35)

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=35 题目: 表达式求值 时间限制:3000 ms | 内存限制:65535 KB描述 AC ...

随机推荐

  1. Failed to load resource: the server responded with a status of 404 ()

    今天遇到了一个一开始感觉很莫名其妙的报错 在编写页面的时候把原先写在html页面里的js代码单独拿出来做成一个JavaScriptUtil文件,放在了和html页面同一个目录下.运行之后在对应的页面c ...

  2. 使用GO语言通过Stream Load实现Doris数据导入

    Doris github地址欢迎加Star apache/incubator-doris: Apache Doris(Incubating) is an MPP-based interactive S ...

  3. 如何配置JAVA环境并安装IEAD软件

    安装IDEA软件之前需要做哪些准备? 在安装IDEA软件之前,需要先确定电脑中有没有JDK,如果没有需要先安装JDK. JDK是整个JAVA的核心,包括了Java运行环境,Java工具(javac/j ...

  4. 攻防世界-MISC:glance-50

    这是攻防世界MISC高手进阶区的题目,题目如下: 点击下载附件一,得到一张GIF动图如下 找个网站给分离一下,将gif分离为图片,共201张,然后拼接在一起即可得到flag 所以这道题的flag如下: ...

  5. [AcWing 75] 和为S的两个数字

    点击查看代码 class Solution { public: vector<int> findNumbersWithSum(vector<int>& nums, in ...

  6. 记录一下l联想Y7000安装双系统(win10+ubuntu16.04)

    单位新配的联想拯救者Y7000,感觉很不错哈,先上一张图. 说实在的,装这个有些小坑,我最开始是直接在原装win10上去装双系统的,结果死活装不上,还把原装win10给折腾没了,哈哈,好逗,以前装双系 ...

  7. VSCODE调试时在cygwin.S中发生段错误

    起因: C++实现矩阵类和向量类 当看了我实现的矩阵类后,一个同学问我: 然后我就试了试1000维,结果运行时在cygwin.S里引发了奇奇怪怪的Segmentation fault,而且这个文件还是 ...

  8. 【python疫情可视化】用pyecharts开发全国疫情动态地图,效果酷炫!

    一.效果演示 我用python开发了一个动态疫情地图,首先看下效果: 如图所示,地图根据实时数据通过时间线轮播的方式,动态展示数据的变化.随着时间的推移,疫情确诊数量的增多,地图各个省份颜色逐渐加深, ...

  9. Go内存管理一文足矣

    最早学习C.C++语言时,它们都是把内存的管理全部交给开发者,这种方式最灵活但是也最容易出问题,对人员要求极高:后来出现的一些高级语言像Java.JavaScript.C#.Go,都有语言自身解决了内 ...

  10. 数仓选型必列入考虑的OLAP列式数据库ClickHouse(上)

    概述 定义 ClickHouse官网地址 https://clickhouse.com/ 最新版本22.4.5.9 ClickHouse官网文档地址 https://clickhouse.com/do ...