题解 P2186 【小Z的栈函数】

Hatsune_Miku

2017-11-09 16:37:49

Solution

前一段时间我校大佬都在做的一道模拟题。我一个蒟蒻也来凑个热闹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; } ```