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;
}
posted @   MituFun  阅读(69)  评论(0编辑  收藏  举报
编辑推荐:
· .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技术实操系列(六):基于图像分类模型对图像进行分类
点击右上角即可分享
微信分享提示