P2186 小 Z 的栈函数 题解
题外话
很简单的一道题,感觉评不上蓝题,最多黄封顶了(
思路
题目中有 \(11\) 个操作,我们可以使用一个数组来保存每次操作。在我的代码中,\(\text{step}_i\) 表示第 \(i\) 个操作是哪一个,\(\text{val}_i\) 表示的是第 \(i\) 个操作 \(x\) 的值(只适用于 \(\text{ADD}\) 操作)。
对于模拟栈的话,大可不必手写一份,直接使用 C++ 自带的 STL stack 即可,很方便。
下面我一行一行解释代码:
const int maxstep = 2010;
int step[maxstep];
int val[maxstep];
int cnt;
stack<int> st;
一个常量 \(\text{maxstep}\) 来表示最大的操作数。
定义储存答案的 \(\text{stack}\) 类型的 st,\(\text{step}_i\) 表示第 \(i\) 个操作是哪一个,\(\text{val}_i\) 表示的是第 \(i\) 个操作 \(x\) 的值(只适用于 \(\text{ADD}\) 操作)。
bool checkError(int x) {
return abs(x) > 1000000000;
}
判断是否操作的时候数据过大。
signed main() {
string str;
do {
cnt++;
cin >> str;
if (str == "NUM") {
step[cnt] = 1;
cin >> val[cnt];
}
if (str == "POP") {
step[cnt] = 2;
}
if (str == "INV") {
step[cnt] = 3;
}
if (str == "DUP") {
step[cnt] = 4;
}
if (str == "SWP") {
step[cnt] = 5;
}
if (str == "ADD") {
step[cnt] = 6;
}
if (str == "SUB") {
step[cnt] = 7;
}
if (str == "MUL") {
step[cnt] = 8;
}
if (str == "DIV") {
step[cnt] = 9;
}
if (str == "MOD") {
step[cnt] = 10;
}
} while (str != "END");
int n;
cin >> n;
while (n--) {
int x;
cin >> x;
f(x);
}
return 0;
}
输入操作和 f 函数传入的值,并保存操作步骤到 \(\text{step}\) 数组和 \(\text{val}\) 数组中。
void f(int x) {
while (!st.empty()) {
st.pop();
}
st.push(x);
if (checkError(x)) {
cout << "ERROR" << endl;
return;
}
for (int cmd = 1; cmd <= cnt; cmd++) {
if (step[cmd] == 1) {
st.push(val[cmd]);
}
if (step[cmd] == 2) {
if (st.size() < 1) {
cout << "ERROR" << endl;
return;
}
st.pop();
}
if (step[cmd] == 3) {
if (st.size() < 1) {
cout << "ERROR" << endl;
return;
}
int t = st.top();
st.pop();
st.push(-t);
if (checkError(t)) {
cout << "ERROR" << endl;
return;
}
}
if (step[cmd] == 4) {
if (st.size() < 1) {
cout << "ERROR" << endl;
return;
}
int t = st.top();
st.push(t);
if (checkError(t)) {
cout << "ERROR" << endl;
return;
}
}
if (step[cmd] == 5) {
if (st.size() < 2) {
cout << "ERROR" << endl;
return;
}
int a = st.top();
st.pop();
int b = st.top();
st.pop();
st.push(a), st.push(b);
if (checkError(a) || checkError(b)) {
cout << "ERROR" << endl;
return;
}
}
if (step[cmd] == 6) {
if (st.size() < 2) {
cout << "ERROR" << endl;
return;
}
int a = st.top();
st.pop();
int b = st.top();
st.pop();
if (checkError(a + b)) {
cout << "ERROR" << endl;
return;
}
st.push(a + b);
}
if (step[cmd] == 7) {
if (st.size() < 2) {
cout << "ERROR" << endl;
return;
}
int a = st.top();
st.pop();
int b = st.top();
st.pop();
if (checkError(b - a)) {
cout << "ERROR" << endl;
return;
}
st.push(b - a);
}
if (step[cmd] == 8) {
if (st.size() < 2) {
cout << "ERROR" << endl;
return;
}
int a = st.top();
st.pop();
int b = st.top();
st.pop();
if (checkError(a * b)) {
cout << "ERROR" << endl;
return;
}
st.push(a * b);
}
if (step[cmd] == 9) {
if (st.size() < 2) {
cout << "ERROR" << endl;
return;
}
int a = st.top();
st.pop();
int b = st.top();
st.pop();
if (a == 0) {
cout << "ERROR" << endl;
return;
}
if (checkError(b / a)) {
cout << "ERROR" << endl;
return;
}
st.push(b / a);
}
if (step[cmd] == 10) {
if (st.size() < 2) {
cout << "ERROR" << endl;
return;
}
int a = st.top();
st.pop();
int b = st.top();
st.pop();
if (checkError(b % a)) {
cout << "ERROR" << endl;
return;
}
st.push(b % a);
}
}
if (st.size() > 1) {
cout << "ERROR" << endl;
return;
}
cout << st.top() << endl;
return;
}
计算 \(f(x)\) 的值,只需要从第一个操作到最后一个操作枚举即可。
注意几个点:
- 如果最后栈内不是一个元素,输出 ERROR。
- 在执行 \(\text{DIV}\) 的时候可能会出现除以 0,所以需要判断并输出 ERROR
代码
#include<iostream>
#include<cstring>
#include<stack>
using namespace std;
#define int long long
const int maxstep = 2010;
int step[maxstep];
int val[maxstep];
int cnt;
stack<int> st;
bool checkError(int x) {
return abs(x) > 1000000000;
}
void f(int x) {
while (!st.empty()) {
st.pop();
}
st.push(x);
if (checkError(x)) {
cout << "ERROR" << endl;
return;
}
for (int cmd = 1; cmd <= cnt; cmd++) {
if (step[cmd] == 1) {
st.push(val[cmd]);
}
if (step[cmd] == 2) {
if (st.size() < 1) {
cout << "ERROR" << endl;
return;
}
st.pop();
}
if (step[cmd] == 3) {
if (st.size() < 1) {
cout << "ERROR" << endl;
return;
}
int t = st.top();
st.pop();
st.push(-t);
if (checkError(t)) {
cout << "ERROR" << endl;
return;
}
}
if (step[cmd] == 4) {
if (st.size() < 1) {
cout << "ERROR" << endl;
return;
}
int t = st.top();
st.push(t);
if (checkError(t)) {
cout << "ERROR" << endl;
return;
}
}
if (step[cmd] == 5) {
if (st.size() < 2) {
cout << "ERROR" << endl;
return;
}
int a = st.top();
st.pop();
int b = st.top();
st.pop();
st.push(a), st.push(b);
if (checkError(a) || checkError(b)) {
cout << "ERROR" << endl;
return;
}
}
if (step[cmd] == 6) {
if (st.size() < 2) {
cout << "ERROR" << endl;
return;
}
int a = st.top();
st.pop();
int b = st.top();
st.pop();
if (checkError(a + b)) {
cout << "ERROR" << endl;
return;
}
st.push(a + b);
}
if (step[cmd] == 7) {
if (st.size() < 2) {
cout << "ERROR" << endl;
return;
}
int a = st.top();
st.pop();
int b = st.top();
st.pop();
if (checkError(b - a)) {
cout << "ERROR" << endl;
return;
}
st.push(b - a);
}
if (step[cmd] == 8) {
if (st.size() < 2) {
cout << "ERROR" << endl;
return;
}
int a = st.top();
st.pop();
int b = st.top();
st.pop();
if (checkError(a * b)) {
cout << "ERROR" << endl;
return;
}
st.push(a * b);
}
if (step[cmd] == 9) {
if (st.size() < 2) {
cout << "ERROR" << endl;
return;
}
int a = st.top();
st.pop();
int b = st.top();
st.pop();
if (a == 0) {
cout << "ERROR" << endl;
return;
}
if (checkError(b / a)) {
cout << "ERROR" << endl;
return;
}
st.push(b / a);
}
if (step[cmd] == 10) {
if (st.size() < 2) {
cout << "ERROR" << endl;
return;
}
int a = st.top();
st.pop();
int b = st.top();
st.pop();
if (checkError(b % a)) {
cout << "ERROR" << endl;
return;
}
st.push(b % a);
}
}
if (st.size() > 1) {
cout << "ERROR" << endl;
return;
}
cout << st.top() << endl;
return;
}
signed main() {
string str;
do {
cnt++;
cin >> str;
if (str == "NUM") {
step[cnt] = 1;
cin >> val[cnt];
}
if (str == "POP") {
step[cnt] = 2;
}
if (str == "INV") {
step[cnt] = 3;
}
if (str == "DUP") {
step[cnt] = 4;
}
if (str == "SWP") {
step[cnt] = 5;
}
if (str == "ADD") {
step[cnt] = 6;
}
if (str == "SUB") {
step[cnt] = 7;
}
if (str == "MUL") {
step[cnt] = 8;
}
if (str == "DIV") {
step[cnt] = 9;
}
if (str == "MOD") {
step[cnt] = 10;
}
} while (str != "END");
int n;
cin >> n;
while (n--) {
int x;
cin >> x;
f(x);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类