信奥赛-刷题笔记-栈篇-T2-P1981表达式求值0517
总题单
本部分总题单如下
【腾讯文档】副本-CSP-JS+NOI 题单 (未完待续)
https://docs.qq.com/sheet/DSmJuVXR4RUNVWWhW?tab=BB08J2
栈篇题单
P1981 [NOIP 2013 普及组] 表达式求值
题目背景
NOIP2013 普及组 T2
题目描述
给定一个只包含加法和乘法的算术表达式,请你编程计算表达式的值。
输入格式
一行,为需要你计算的表达式,表达式中只包含数字、加法运算符 +
和乘法运算符 *
,且没有括号,所有参与运算的数字均为 0 0 0 到 2 31 − 1 2^{31}-1 231−1 之间的整数。
输入数据保证这一行只有 0123456789+*
这 12 12 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
代码1
#include <cstdio>
const int mod = 10000;
int x,s,t; //x是当前的数,s是和,t是当前段的乘积
char c;
int main(){scanf("%d",&t);//先读入第一个数,之后每次读入一个符号一个数while(scanf("%c",&c) && c != '\n'){ //最后会读到换行符scanf("%d",&x);if(c == '*') t = t * x % mod; //是乘号就相乘else s = (s + t) % mod,t = x;//加号就加上上一段的积,t变为下一段的第一个数}printf("%d\n",(s + t) % mod); //加上最后一段的积return 0;
}
代码2
#include <iostream>
#include <stack>
#include<cstdio>
using namespace std;// 定义一个栈来存储计算过程中的数字
stack<int> numStack; // 用于存储参与运算的数字,并在最后将它们相加int main() {int a, b; // 变量a用于存储当前读取到的数字,b用于存储下一个数字char c; // 变量c用于存储当前读取到的操作符('+', '*')// 首先读取第一个数字,并对其进行10000取模以确保结果长度不超过4位cin >> a;int modValue = 10000; // 设置模值为10000,用于控制输出结果的最大长度a = a % modValue;numStack.push(a); // 将处理后的数字压入栈中// 循环读取操作符和数字,直到输入结束while (scanf("%c",&c) && c != '\n') {scanf("%d",&b);if (c == '*') { // 如果当前操作符是乘法// 弹出栈顶元素(最近一次存储的数字)并进行乘法运算a = numStack.top();numStack.pop();// 将乘积对modValue取模后重新压入栈中numStack.push((a * b) % modValue);} else { // 如果当前操作符是加法// 直接将数字b压入栈中,等待后续累加numStack.push(b);}}// 初始化变量a为0,用于累加栈中的所有数字a = 0;// 累加栈中的所有数字,并对每次累加的结果都进行取模操作while (!numStack.empty()) {a += numStack.top();a %= modValue; // 对累加结果取模,保证最终结果的长度不超过4位numStack.pop(); // 弹出栈顶元素}// 输出最终结果cout << a << endl;return 0;
}
说明/提示
对于 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。
现场真题注意事项
https://cspoj.com/contest.php?cid=1002Fus5yz4x3EcSJH1Z
注意事项
文件名(程序名和输入输出文件名)必须使用英文小写。(提交必须使用freopen()进行提交)
C/C++ 中函数 main() 的返回值类型必须是 int,程序正常结束时的返回值必须是0。
提交的程序代码文件的放置位置请参考各省的具体要求。
因违反以上三点而出现的错误或问题,申述时一律不予受理。
若无特殊说明,结果的比较方式为全文比较(过滤行末空格及文末回车)。
程序可使用的栈空间内存限制与题目的内存限制一致。
全国统一评测时采用的机器配置为:Inter® Core™ i7-8700K CPU @3.70GHz,内存 32GB。上述时限以此配置为准。
只提供 Linux 格式附加样例文件。
评测在当前最新公布的 NOI Linux 下进行,各语言的编译器版本以此为准
假设输入样例数据存在文件test.in中,输出样例数据存在文件test.out中,
则在CSP、NOI等比赛的代码中,需添加freopen、fclose语句,
内容详见模板代码如下。
#include <bits/stdc++.h>
#include<cstdio>//必须包含cstdio头文件
#include<iostream>
using namespace std;int main(){freopen("test.in","r",stdin);freopen("test.out","w",stdout);cout<<"Hello NOI"<<endl;fclose(stdin);fclose(stdout);return 0;
}
复制
下面为函数的简介,详细可参见 http://www.cplusplus.com/reference/clibrary/cstdio/freopen.html
函数名:freopen
声明:FILE freopen( const char path, const char mode, FILE stream );
所在文件: stdio.h
参数说明:
path: 文件名,用于存储输入输出的自定义文件名。
mode: 文件打开的模式。和fopen中的模式(如r-只读, w-写)相同。
stream: 一个文件,通常使用标准流文件。
返回值:成功,则返回一个path所指定文件的指针;失败,返回NULL。(一般可以不使用它的返回值)
功能:实现重定向,把预定义的标准流文件定向到由path指定的文件中。标准流文件具体是指stdin、stdout和stderr。其中stdin是标准输入流,默认为键盘;stdout是标准输出流,默认为屏幕;stderr是标准错误流,一般把屏幕设为默认。通过调用freopen,就可以修改标准流文件的默认值,实现重定向。
#include<iostream>
#include<cstdio>
using namespace std;
int main(){freopen("7532.in", "r", stdin);freopen("7532.out", "w", stdout);//原来的代码保持不变double a, b, r;int k;cin >> a >> b;k = int(a/b);r = a - b * k;printf("%g", r);//-------------fclose(stdin);fclose(stdout);return 0;
}