题解 P2186 【小Z的栈函数】
Hatsune_Miku
2017-11-09 16:37:49
前一段时间我校大佬都在做的一道模拟题。我一个蒟蒻也来凑个热闹23333...
主要的难点在于函数太多,还有附加的限制条件。
主要的判错有:
- 每次入栈检查绝对值是否超出限制
- 对栈内元素进行操作前先检查栈内元素的数量
- 除以零的情况
- 运算结果的绝对值是否超出限制
- 函数最后栈内元素个数
在WA了一次后,我重新写了一次代码,希望能帮助查错而定义了一大堆常量,希望对大家有帮助。
毕竟模拟题吗,细心一点总是能做对的。
我的思路比较糟糕,每一个判错都是分开写的,11个函数也是分开的,还手写了几个辅助函数。程序中所有的操作都统一由EXECUTE函数接管,出现错误则使用HANDLE\_ERROR函数进行输出。
不知道为什么,指令不能用正常的方式读入,就手写了一个read\_instruction函数来读入(果然还是太弱了)。
还是惯例,能用STL的地方用的都是STL。
如果还不理解的话代码里有注释:
```cpp
#include<cstdio>
#include<string>
#include<stack>
using namespace std;
stack<long long> s; //栈
pair<long long,long long>ret; //GET函数返回栈顶两个元素形成的二元组
string instruction[2000+10]; //指令
long long number[2000+10]; //NUM函数的操作数
int cnt,n,ai; //cnt:指令数
bool fail; //函数是否中途失败退出
//*********状态常量表开始**********//
#define OVERFLOW_FAIL 1
#define OVERFLOW_OK 2
#define NUM_FAIL_OVERFLOW 3
#define NUM_OK 4
#define UNDERFLOW_FAIL 5
#define UNDERFLOW_OK 6
#define POP_FAIL_UNDERFLOW 7
#define POP_OK 8
#define INV_FAIL_UNDERFLOW 9
#define INV_OK 10
#define DUP_FAIL_UNDERFLOW 11
#define DUP_OK 12
#define GET_FAIL_UNDERFLOW 13
#define GET_OK 14
#define SWP_FAIL_UNDERFLOW 15
#define SWP_OK 16
#define ADD_FAIL_UNDERFLOW 17
#define ADD_FAIL_OVERFLOW 18
#define ADD_OK 19
#define SUB_FAIL_UNDERFLOW 20
#define SUB_FAIL_OVERFLOW 21
#define SUB_OK 22
#define MUL_FAIL_UNDERFLOW 23
#define MUL_FAIL_OVERFLOW 24
#define MUL_OK 25
#define DIVISION_FAIL 26
#define DIVISION_OK 27
#define DIV_FAIL_UNDERFLOW 28
#define DIV_FAIL_DIVISION_BY_ZERO 29
#define DIV_FAIL_OVERFLOW 30
#define DIV_OK 31
#define MOD_FAIL_UNDERFLOW 32
#define MOD_FAIL_DIVISION_BY_ZERO 33
#define MOD_FAIL_OVERFLOW 34
#define MOD_OK 35
#define SIZE_ERROR 36
//*********状态常量表结束**********//
inline long long abs(long long val) { //辅助函数,求绝对值
if(val>=0)return val;
else return -val;
}
inline int OVERFLOW(long long val) { //判错函数,绝对值超出限制
if(abs(val)>1000000000ll)
return OVERFLOW_FAIL;
return OVERFLOW_OK;
}
inline int NUM(long long x) {
if(OVERFLOW_FAIL==OVERFLOW(x))
return NUM_FAIL_OVERFLOW;
s.push(x);
return NUM_OK;
}
inline int UNDERFLOW(int val) { //判错函数,操作后栈会下溢出
if(s.size()<val)
return UNDERFLOW_FAIL;
return UNDERFLOW_OK;
}
inline int POP() {
if(UNDERFLOW_FAIL==UNDERFLOW(1))
return POP_FAIL_UNDERFLOW;
s.pop();
return POP_OK;
}
inline int INV() {
if(UNDERFLOW_FAIL==UNDERFLOW(1))
return INV_FAIL_UNDERFLOW;
long long tmp=s.top();
s.pop();
s.push(-tmp);
return INV_OK;
}
inline int DUP() {
if(UNDERFLOW_FAIL==UNDERFLOW(1))
return DUP_FAIL_UNDERFLOW;
s.push(s.top());
return DUP_OK;
}
inline int GET() { //辅助函数,取出栈顶两个元素
if(UNDERFLOW_FAIL==UNDERFLOW(2))
return GET_FAIL_UNDERFLOW;
ret.first=s.top(),s.pop(),ret.second=s.top(),s.pop();
return GET_OK;
}
inline int SWP() {
if(GET_FAIL_UNDERFLOW==GET())
return SWP_FAIL_UNDERFLOW;
s.push(ret.first),s.push(ret.second);
return SWP_OK;
}
inline int ADD() {
if(GET_FAIL_UNDERFLOW==GET())
return ADD_FAIL_UNDERFLOW;
long long tmp=ret.first+ret.second;
if(OVERFLOW_FAIL==OVERFLOW(tmp))
return ADD_FAIL_OVERFLOW;
s.push(tmp);
return ADD_OK;
}
inline int SUB() {
if(GET_FAIL_UNDERFLOW==GET())
return SUB_FAIL_UNDERFLOW;
long long tmp=ret.second-ret.first;
if(OVERFLOW_FAIL==OVERFLOW(tmp))
return SUB_FAIL_OVERFLOW;
s.push(tmp);
return SUB_OK;
}
inline int MUL() {
if(GET_FAIL_UNDERFLOW==GET())
return MUL_FAIL_UNDERFLOW;
long long tmp=ret.first*ret.second;
if(OVERFLOW_FAIL==OVERFLOW(tmp))
return MUL_FAIL_OVERFLOW;
s.push(tmp);
return MUL_OK;
}
inline int DIVISION(long long division) { //判错函数,被零除
if(division==0)
return DIVISION_FAIL;
return DIVISION_OK;
}
inline int DIV() {
if(GET_FAIL_UNDERFLOW==GET())
return DIV_FAIL_UNDERFLOW;
if(DIVISION_FAIL==DIVISION(ret.first))
return DIV_FAIL_DIVISION_BY_ZERO;
long long tmp=ret.second/ret.first;
if(OVERFLOW_FAIL==OVERFLOW(tmp))
return DIV_FAIL_OVERFLOW;
s.push(tmp);
return DIV_OK;
}
inline int MOD() {
if(GET_FAIL_UNDERFLOW==GET())
return MOD_FAIL_UNDERFLOW;
if(DIVISION_FAIL==DIVISION(ret.first))
return MOD_FAIL_DIVISION_BY_ZERO;
long long tmp=ret.second%ret.first;
if(OVERFLOW_FAIL==OVERFLOW(tmp))
return MOD_FAIL_OVERFLOW;
s.push(tmp);
return MOD_OK;
}
inline void HANDLE_ERROR(int ret) { //辅助函数,传递错误,如果函数没有执行成功则执行
if(fail==false)
printf("ERROR\n",ret);
fail=true;
return;
}
inline void EXECUTE(int ret) { //辅助函数,如果函数没有执行成功则传递错误
if(ret!=NUM_OK&&ret!=POP_OK&&ret!=INV_OK&&ret!=DUP_OK&&ret!=SWP_OK
&&ret!=ADD_OK&&ret!=SUB_OK&&ret!=MUL_OK&&ret!=DIV_OK&&ret!=MOD_OK)
HANDLE_ERROR(ret);
}
inline string read_instruction() { //辅助函数,读取指令
string str="";
char ch=getchar();
while(ch<'A'||ch>'Z')ch=getchar();
str+=ch,str+=getchar(),str+=getchar();
return str;
}
int main() {
while(1) {
instruction[cnt]=read_instruction();
if(instruction[cnt]=="END")
break;
if(instruction[cnt]=="NUM")
scanf("%d",&number[cnt]);
cnt++;
}
scanf("%d",&n);
for(int i=0; i<n; i++) {
scanf("%d",&ai);
NUM(ai); //先把初始元素压入栈中,同样需要判错
for(int i=0; i<cnt; i++) {
if(instruction[i]=="NUM")EXECUTE(NUM(number[i]));
if(instruction[i]=="POP")EXECUTE(POP());
if(instruction[i]=="INV")EXECUTE(INV());
if(instruction[i]=="DUP")EXECUTE(DUP());
if(instruction[i]=="SWP")EXECUTE(SWP());
if(instruction[i]=="ADD")EXECUTE(ADD());
if(instruction[i]=="SUB")EXECUTE(SUB());
if(instruction[i]=="MUL")EXECUTE(MUL());
if(instruction[i]=="DIV")EXECUTE(DIV());
if(instruction[i]=="MOD")EXECUTE(MOD());
if(fail==true)
break;
}
if(!fail&&s.size()==1) //如果没有函数执行失败并且栈中仅有一个元素
printf("%d\n",s.top());
else HANDLE_ERROR(SIZE_ERROR);
while(!s.empty()) //清空栈,准备下一次操作
s.pop();
fail=false; //复原函数执行状态
}
return 0;
}
```