题解 P2186 【小Z的栈函数】

2017-11-09 16:37:49


前一段时间我校大佬都在做的一道模拟题。我一个蒟蒻也来凑个热闹23333...

主要的难点在于函数太多,还有附加的限制条件。

主要的判错有:

  • 每次入栈检查绝对值是否超出限制

  • 对栈内元素进行操作前先检查栈内元素的数量

  • 除以零的情况

  • 运算结果的绝对值是否超出限制

  • 函数最后栈内元素个数

在WA了一次后,我重新写了一次代码,希望能帮助查错而定义了一大堆常量,希望对大家有帮助。

毕竟模拟题吗,细心一点总是能做对的。

我的思路比较糟糕,每一个判错都是分开写的,11个函数也是分开的,还手写了几个辅助函数。程序中所有的操作都统一由EXECUTE函数接管,出现错误则使用HANDLE_ERROR函数进行输出。

不知道为什么,指令不能用正常的方式读入,就手写了一个read_instruction函数来读入(果然还是太弱了)。

还是惯例,能用STL的地方用的都是STL。

如果还不理解的话代码里有注释:

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