zoukankan      html  css  js  c++  java
  • UVA 1661 Equation (后缀表达式,表达式树,模拟,实现)

    题意:给出一个后缀表达式f(x),最多出现一次x,解方程f(x) = 0。

    读取的时候用一个栈保存之前的结点,可以得到一颗二叉树,标记出现'X'的路径,先把没有出现'X'的子树算完,由于读取建树的时候是由底向上的,

    这步可以在读取的时候顺带完成。

    注意'X'或'1/x'在某个结点和'0'相乘,那么'X'等效与没有出现过,把之后的结点标记为常数。

    然后dfs模拟运算和移项。

    还有一些输入输出的小细节和几组测试数据,具体看代码。

    WA了很多发,去找数据手动对拍好久终于发现(1/(1/x))=0这种情况是被当作无解。。。而我当作x = 0来处理了,QAQ。为何解个一元一次如此艰辛。。。

    第一次写5000B+,模拟真的很难写有没有。手写一个分数的模板

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn = 666;
    typedef long long ll;
    
    ll gcd(ll a,ll b) { return b?gcd(b,a%b):a; }
    
    struct Fra
    {
        ll p,q;
        Fra(ll x = 0,ll y = 1):p(x),q(y){ normal(p,q); }
        void normal(ll &p,ll &q) { ll g = gcd(p,q); p/=g; q/=g; }
        Fra operator = (int x) {  p = x; q = 1; return *this; }
        Fra operator = (ll x) { p = x; q = 1; return *this; }
        Fra operator - () { return {-p,q}; }
        Fra operator + (Fra &r) {
            ll m,n;
            m = p*r.q+r.p*q;
            n = q*r.q;
            normal(m,n);
            return {m,n};
        }
        Fra operator += (Fra& r) { return *this = *this+r; }
        Fra operator - (Fra &r) { return (-r) + *this; }
        Fra operator -= (Fra &r) { return *this = *this-r; }
        Fra operator * (Fra &r) {
            ll m,n;
            m = p*r.p;
            n = q*r.q;
            normal(m,n);
            return {m,n};
        }
        Fra operator *= (Fra &r) { return (*this) = (*this)*r; }
        Fra operator /(Fra &r) { return Fra(r.q,r.p) * (*this); }
        Fra operator /=(Fra &r) { return (*this) = (*this)/r; }
        bool operator == (const Fra& r) const { return p*r.q == r.p*q; }
        bool operator < (Fra& r) { return  p*r.q < r.p*q; }
        void print() { normal(p,q); if(q<0)q = -q,p = -p; printf("%lld/%lld
    ",p,q); }
    };
    
    
    struct Node
    {
        Node* l,*r;
        Fra f; char op;
        bool fx;
        Node(){};
        Node(Fra &v,Node*a = NULL, Node*b = NULL):f(v),l(a),r(b){};
    
    }nd[maxn];
    
    bool isOp[256];
    char rev[256];
    
    Fra cal(Fra &x,Fra &y,char op)
    {
        //assert(isOp[op] == true)
        switch(op){
            case '+':return x+y;
            case '-': return x-y;
            case '*': return x*y;
            case '/': return x/y;
        }
        return {233,1};
    }
    
    Fra ans;
    
    void calRev(Fra &x,char op)
    {
        switch(op){
            case'+':ans-=x; return;
            case'*':ans/=x; return ;
            case'-':ans = x-ans; return;
            case'/':ans = x/ans; return;
        }
    }
    
    //之前要预处理
    bool dfs(Node* u)
    {
        //*u;
        if(u->l == NULL) return true;
        //assert(u.r)
        if(u->l->fx){
            ans = cal(ans,u->r->f,rev[u->op]); //乘以0的情况已经预处理了
            if(!dfs(u->l)) return false;
        }else if(u->r->fx) {
            calRev(u->l->f,u->op);//移项,ans本身可能会是0
            if(ans.q == 0) { return false; }
            if(!dfs(u->r)) return false;
        }
        return true;
    }
    
    Node* read(char ch)
    {
        int cnt = 0;
            stack<Node*> stk;
            do{
                while(ch == ' ')ch = getchar();
                Node &cur = nd[cnt];
                if(isOp[ch]){
                    cur.op = ch;
                    cur.r = stk.top(); stk.pop();
                    cur.l = stk.top(); stk.pop();
                    cur.fx = cur.l->fx || cur.r->fx;
                    if(cur.fx){ //系数为0的处理
                        if((cur.op == '*' && (cur.r->fx ? cur.l->f == 0 : cur.r->f == 0))
                        || (cur.op == '/' && cur.r->fx && cur.l->f == 0) ) {
                            cur.fx = false;
                            cur.f = 0; cur.l = cur.r = NULL;
                        }
                    }else { //预处理,边读边算
                        cur.f = cal(cur.l->f,cur.r->f,cur.op);
                        cur.l = cur.r = NULL;
                    }
                }else {
                    if(ch == 'X'){
                        cur.fx = true;
                    }else {
                        cur.fx = false;
                        int data = ch-'0';
                        while(ch = getchar(), ch>='0'&&ch<='9') data = data*10+ch-'0';
                        cur.f = data;
                    }
                    cur.l = cur.r = NULL;
                }
                stk.push(nd+cnt);
                ch = getchar(); cnt++;
            }while(ch != '
    '&&~ch);
        return stk.top();
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        isOp['+'] = isOp['-'] = isOp['*'] = isOp['/'] = true;
        rev['+'] = '-'; rev['-'] = '+'; rev['*'] = '/'; rev['/'] = '*';
        char head;
        while(~(head = getchar())){
            Node* root = read(head);
            if(!root->fx) {
                if(root->f == 0) puts("MULTIPLE");
                else puts("NONE");
                continue;
            }
            ans = 0;
            if(dfs(root)){ printf("X = "); ans.print(); }
            else {puts("NONE"); continue; }
        }
        return 0;
    }
    
    /*
    1 1 X / /
    1 1 X 2 - / /
    
    
    1 X /
    0 X * 1 +
    0 X / 1 +
    
    9 9 9 9 9 9 9 9 9 9 9 9 9 X 1 * * * * * * * * * * * * * +
    7 6 - 8 / 8 2 * / 0 3 - + 5 5 1 / + 1 X 2 + + 8 8 + + * +
    7 8 X + * 1 8 5 7 3 + * * 7 6 6 / 3 + + 6 5 7 / - * / / +
    */
  • 相关阅读:
    第七届蓝桥杯JavaA组省赛真题
    第七届蓝桥杯JavaA组省赛真题
    第七届蓝桥杯JavaA组省赛真题
    第七届蓝桥杯JavaA组省赛真题
    Qt自定义model
    Qt Model/View(官方翻译,图文并茂)
    ddd
    java整合spring和hadoop HDFS
    hadoop-2.7.3 在windows环境下安装(无需Cygwin)
    Web Api 自动生成帮助文档
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4769144.html
Copyright © 2011-2022 走看看