zoukankan      html  css  js  c++  java
  • UVALive 5888 Stack Machine Executor (栈+模拟)

    Stack Machine Executor

    题目链接:

    http://acm.hust.edu.cn/vjudge/problem/26636

    Description

    http://7xjob4.com1.z0.glb.clouddn.com/7df4b3c52d86b5aca54ec47060e43f56

    Input

    The input contains description of several machines. Each machine is described by two parts: the program and the input section. The program is given by a series of instructions, one per line. Every instruction is given by three uppercase letters and there must not be any other characters. The only exception is the NUM instruction, which has exactly one space after the three letters followed by a non-negative integer number between 0 and 109 . The only allowed instructions are those defined above. Each program is terminated by a line containing the word ‘END’ (and nothing else). The input section starts with an integer N (0 ≤ N ≤ 10000), the number of program executions. The next N lines contain one number each, specifying an input value Vi , 0 ≤ Vi ≤ 109 . The program should be executed once for each of these values independently, every execution starting with the stack containing one number — the input value Vi . There is one empty line at the and of each machine description. The last machine is followed by a line containing the word ‘QUIT’. No program will contain more than 100 000 instructions and no program requires more than 1 000 numbers on the stack in any moment during its execution.

    Output

    For each input value, print one line containing the output value for the corresponding execution, i.e., the one number that will be on the stack after the program executes with the initial stack containing only the input number. If there is a program failure during the execution or if the stack size is incorrect at the end of the run (either empty or there are more numbers than one), print the word ‘ERROR’ instead. Print one empty line after each machine, including the last one.

    Sample Input

    DUP MUL NUM 2 ADD END 3 1 10 50 NUM 1 NUM 1 ADD END 2 42 43 NUM 600000000 ADD END 3 0 600000000 1 QUIT

    Sample Output

    3 102 2502 ERROR ERROR 600000000 ERROR 600000001

    Source

    2016-HUST-线下组队赛-1
    ##题意: 给出一系列与栈相关的指令序列. 求对每一组指令集给定一个初始值时,是否会出现非法操作,如果不会则输出栈中唯一的数.
    ##题解: 首先明确会ERROR的情况: 操作数不够、除/模零、结果超出限制、结果栈的元素个数不是一. 一开始以为数据规模太大直接模拟可能过不了,而实际上数据非常小... 对各种操作进行模拟即可,注意各种细节的处理. (除和模与内置运算一致,不需要重载) (注意字符串的读入和数据大小) 以下的代码中,先对指令序列出现操作数不够的情况进行了预处理,方便后面的判断.
    ##代码: ``` cpp #include #include #include #include #include #include #include #include #include #include #include #define maxn 401000 #define MAX 1000000000 #define inf 0x3f3f3f3f #define mod 1000000007 #define LL long long #define mid(a,b) ((a+b)>>1) #define IN freopen("in.txt", "r", stdin); #define OUT freopen("out.txt", "w", stdout); using namespace std;

    define NUM 0

    define POP 1

    define INV 2

    define DUP 3

    define SWP 4

    define ADD 5

    define SUB 6

    define MUL 7

    define DIV 8

    define MOD 9

    int cnt;
    char op[50];
    int ops[maxn];
    LL op_num[maxn];
    bool flag;
    stack s;

    int transop() {
    if (op[0] == 'N') return NUM;
    else if (op[0] == 'P') return POP;
    else if (op[0] == 'I') return INV;
    else if (op[0] == 'D' && op[1] == 'U') return DUP;
    else if (op[0] == 'A') return ADD;
    else if (op[0] == 'S' && op[1] == 'W') return SWP;
    else if (op[0] == 'S' && op[1] == 'U') return SUB;
    else if (op[0] == 'M' && op[1] == 'U') return MUL;
    else if (op[0] == 'D' && op[1] == 'I') return DIV;
    else if (op[0] == 'M' && op[1] == 'O') return MOD;
    }

    int main()
    {
    //IN;

    while(scanf("%s", op) != EOF)
    {
        if (op[0] == 'Q') break;
    
        cnt = 0;  flag = 1;
        while(!s.empty()) s.pop();
        int stack_num = 1;
    
        while (1) {
            if (op[0] == 'E') break;
            ops[++cnt] = transop();
            if(ops[cnt] == NUM) {
                scanf("%lld", &op_num[cnt]);
                stack_num++;
            }
            if(ops[cnt] == POP) {
                if(stack_num < 1) flag = 0;
                stack_num--;
            }
            if(ops[cnt] == INV) {
                if(stack_num < 1) flag = 0;
            }
            if(ops[cnt] == DUP) {
                if(stack_num < 1) flag = 0;
                stack_num++;
            }
            if(ops[cnt] == SWP) {
                if(stack_num < 2) flag = 0;
            }
            if(ops[cnt] == ADD || ops[cnt] == SUB || ops[cnt] == MUL || ops[cnt] == DIV || ops[cnt] == MOD) {
                if(stack_num < 2) flag = 0;
                stack_num--;
            }
    
            scanf("%s", op);
        }
    
        if(stack_num != 1) flag = 0;
    
        int m; scanf("%d", &m);
        while(m--) {
            LL x;
            scanf("%lld", &x);
            while(!s.empty()) s.pop();
            s.push(x);
            if(!flag) {
                puts("ERROR"); continue;
            }
    
            bool flag2 = 1;
            for(int i=1; i<=cnt; i++) {
                if(ops[i] == NUM) {
                    s.push(op_num[i]);
                }
                if(ops[i] == POP) {
                    s.pop();
                }
                if(ops[i] == INV) {
                    LL cur = s.top(); s.pop();
                    s.push(-cur);
                }
                if(ops[i] == DUP) {
                    s.push(s.top());
                }
                if(ops[i] == SWP) {
                    LL cur1 = s.top(); s.pop();
                    LL cur2 = s.top(); s.pop();
                    s.push(cur1);
                    s.push(cur2);
                }
                if(ops[i] == ADD) {
                    LL cur1 = s.top(); s.pop();
                    LL cur2 = s.top(); s.pop();
                    if(cur1 + cur2 > MAX || cur1 + cur2 < -MAX) {
                        flag2 = 0;
                        break;
                    }
                    s.push(cur1 + cur2);
                }
                if(ops[i] == SUB) {
                    LL cur1 = s.top(); s.pop();
                    LL cur2 = s.top(); s.pop();
                    if(cur2 - cur1 > MAX || cur2 - cur1 < -MAX) {
                        flag2 = 0;
                        break;
                    }
                    s.push(cur2 - cur1);
                }
                if(ops[i] == MUL) {
                    LL cur1 = s.top(); s.pop();
                    LL cur2 = s.top(); s.pop();
                    if(cur2 * cur1 > MAX || cur2 * cur1 < -MAX) {
                        flag2 = 0;
                        break;
                    }
                    s.push(cur2 * cur1);
                }
                if(ops[i] == DIV) {
                    LL cur1 = s.top(); s.pop();
                    LL cur2 = s.top(); s.pop();
                    if(!cur1) {
                        flag2 = 0;
                        break;
                    }
                    LL tmp = cur2 / cur1;
                    s.push(tmp);
                }
                if(ops[i] == MOD) {
                    LL cur1 = s.top(); s.pop();
                    LL cur2 = s.top(); s.pop();
                    if(!cur1) {
                        flag2 = 0;
                        break;
                    }
                    LL tmp = cur2 % cur1;
                    s.push(tmp);
                }
            }
    
            if(!flag2) puts("ERROR");
            else printf("%lld
    ", s.top());
        }
    
        printf("
    ");
    }
    
    return 0;
    

    }

  • 相关阅读:
    MongoDB 基础学习
    在 PostgreSQL 中使用码农很忙 IP 地址数据库
    在 MySQL 中使用码农很忙 IP 地址数据库
    编译opencv和opencv_contrib
    修改本次提交日志
    clone报告超过限制
    修改gitolite管理员
    libevent简介[翻译]11 连接监听:接收一个TCP连接
    libevent简介[翻译]11 Evbuffers:缓冲IO的功能函数
    Windows查看TCP连接数
  • 原文地址:https://www.cnblogs.com/Sunshine-tcf/p/5791178.html
Copyright © 2011-2022 走看看