ZOJ 3952 Fibonacci Sequence Chicken Edition(构造/模拟)

来源:互联网 发布:C语言干什么的 编辑:程序博客网 时间:2024/06/05 10:07

题意

chicken,chicken,chiken…

思路

题目要求用小叽叽写出一个能计算斐波那契第n项的程序,有一个解析器会执行我们的程序,程序的输出就是程序结束时的栈顶元素。

由于程序并没有提供循环/判断的语句,也没有输出的语句,所以我们只能利用copy将元素弄到栈顶,然后结束程序进行输出。

前30项存储斐波那契的值,31-34是缓冲区,存储操作数与被操作值,计算出斐波那契数后复制到相应位置,输出就是相反操作,具体见代码的调试模式。

代码

如果这题像cf一样直接提供parser多好,这样检查比较方便

不过没关系,大不了自己写一个parser。。

#include <bits/stdc++.h>#define mem(a,b) memset(a,b,sizeof(a))#define rep(i,a,b) for(int i=a;i<b;i++)#define sc(a) scanf("%d",&a)const int INF=0x3f3f3f3f;const int maxn=2e5+50;const int mod=1e9+7;const double eps=1e-8;#define pii pair<int,int>typedef long long ll;typedef unsigned int ui;using namespace std;int fib[31];void initFib(){    fib[1]=fib[2]=1;    rep(i,3,31) fib[i]=fib[i-1]+fib[i-2];}struct Parser{    int stk[233];    int pos;    queue<int> inputs;    void push(int x){        stk[pos++]=x;    }    bool empty(){        return pos==0;    }    int size(){        return pos;    }    int top(){        return stk[pos-1];    }    void pop(){        pos--;    }    Parser(const queue<int> &inputs) : inputs(inputs) {pos=0;}    void ERROR(){        puts("ERROR");        exit(-1);    }    void work(int operand){        if(operand>=7) {            push(operand-7);            return;        }        int x,y;        switch (operand){            case 1:                if(size()<2) ERROR();                x=top(); pop();                y=top(); pop();                push(x+y);                break;            case 2:                if(size()<2) ERROR();                x=top(); pop();                y=top(); pop();                push(x-y);                break;            case 3:                if(size()<2) ERROR();                x=top(); pop();                y=top(); pop();                push(x==y);                break;            case 4:                if(inputs.empty()) ERROR();                push(inputs.front());                inputs.pop();                break;            case 5:                if(size()<2) ERROR();                x=top(); pop();                y=top(); pop();                stk[x-1]=stk[y-1];                if(x>pos) {                    printf("pos %d x %d OL\n",pos,x);                    ERROR();                }                break;        }    }    int stop(){        if(empty()) {            ERROR();        }        return top();    }    void printStack(){        printf("stack is ");        rep(i,0,pos) printf("%02d ",stk[i]);        puts("= =");    }};vector<string> ans;inline void pb(string s){    ans.push_back(s);}inline string push(int x){    return string(x+7,'c');}inline string getOp(int x){    return string(x,'c');}inline void copyFrom(int from,int to){    pb(push(from));    pb(push(to));    pb(getOp(5));}inline void readN(){    pb(getOp(4));}inline void add(){    pb(getOp(1));}void work(){    ans.clear();    rep(i,0,30) pb(push(1));    // cal fib(3) to 30    rep(i,3,31){        //safety buf        if(i==3) pb(push(0));        pb(push(0));        copyFrom(i-2,31);        copyFrom(i-1,32);        add();        copyFrom(31,i);    }    readN();    pb(push(31));    pb(getOp(5));}void check(int n){    work();    queue<int> v;    v.push(n);    Parser parser(v);    parser.inputs=v;    for(int i=0;i<ans.size();i++)  {        string op=ans[i];        int sz=op.length();        printf("op %d ",sz);        if(sz==5) puts("copy");        else if(sz==4) puts("read");        else if(sz>=7) printf("push %d\n",sz-7);        else if(sz==1) puts("add");        parser.work(sz);        parser.printStack();    }    printf("%d %d\n",parser.stop(),fib[n]);}int main(){#ifndef ONLINE_JUDGE    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);#endif    bool debug=false;    if(debug){        initFib();        int n;        while(cin>>n){            check(n);        }    }else{        work();        for(int i=0;i<ans.size();i++) cout<<ans[i]<<endl;    }    return 0;}
0 0
原创粉丝点击