码迷,mamicode.com
首页 > 其他好文 > 详细

UVA 1661 Equation

时间:2015-08-29 15:12:54      阅读:617      评论:0      收藏:0      [点我收藏+]

标签:

给出一个后缀表达式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\n",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 != \n&&~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 / - * / / +
*/

 

UVA 1661 Equation

标签:

原文地址:http://www.cnblogs.com/jerryRey/p/4769144.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!