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;
}