Cod sursa(job #1342239)

Utilizator retrogradLucian Bicsi retrograd Data 13 februarie 2015 18:00:09
Problema Bool Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.17 kb
#include<fstream>
#include<vector>
#include<map>
#include<cstring>
#include<algorithm>

using namespace std;
typedef int var;

ifstream fin("bool.in");
ofstream fout("bool.out");

map<string, int> MAP_OP;
map<char, vector<int> > MAP_NUM;


struct Operator {
    var type;
    var pri;
    var ind;
    Operator(var a, var b, var c) {
        type = a;
        pri = b;
        ind = c;
    }
};


vector<Operator> OP;
vector<bool> NUM;
string strip;
bool RES[1001];

char block[1001], c[1001];

bool cmp(Operator a, Operator b) {
    return a.pri > b.pri;
}


var RANK[1001], PARENT[1001];

inline var Find(var t) {
    if(PARENT[t] == t) {
        return t;
    } else {
        PARENT[t] = Find(PARENT[t]);
        return PARENT[t];
    }
}

inline void Union(var r1, var r2, var res) {
    r1 = Find(r1);
    r2 = Find(r2);

    if(RANK[r1] < RANK[r2]) {
        PARENT[r1] = r2;
        RES[r2] = res;
    } else {
        PARENT[r2] = r1;
        RES[r1] = res;
        RANK[r2] = max(RANK[r2], RANK[r1] + 1);
    }
}


bool compute(Operator op) {
    if(2 == op.type) {
        return RES[Find(op.ind-1)]&RES[Find(op.ind)];
    } else if(1 == op.type) {
        return RES[Find(op.ind-1)]|RES[Find(op.ind)];
    }
    return RES[Find(op.ind)]^1;
}

char expr[1002];

int main() {

    MAP_OP["AND"] = 2;
    MAP_OP["OR"] = 1;
    MAP_OP["NOT"] = 3;

    //fin.getline(expr, 1001);

    var curpri = 0;
    var elin = 0;

    //fin.flush();

    fin.getline(expr, 1002);
    char *p = strtok(expr, " ");

    while(p) {
        while(p[0] == '(') {
            p++;
            curpri += 10;
        }
        var npri = 0;
        var len = strlen(p);
        while(p[len-1] == ')') {
            npri -= 10;
            len--;
            p[len] = 0;
        }

        strip = p;

        if(MAP_OP[strip]) {
            OP.push_back(Operator(MAP_OP[strip], curpri + MAP_OP[strip], elin));
        } else {
            if(strip == "TRUE") {
                NUM.push_back(1);
                elin ++;
            } else if(strip == "FALSE") {
                NUM.push_back(0);
                elin++;
            } else {
                MAP_NUM[strip[0]].push_back(NUM.size());
                NUM.push_back(false);
                elin++;
            }
        }

        curpri += npri;
        p = strtok(NULL, " ");
    }

    sort(OP.begin(), OP.end(), cmp);

    int n;
    fin>>n;
    char c;
    for(var i=1; i<=n; i++) {

        fin>>c;
        vector<var> &V = MAP_NUM[c];
        for(vector<var>::iterator it = V.begin(); it != V.end(); ++it) {
            NUM[*it] = 1-NUM[*it];
        }

        for(var i=0; i<NUM.size(); i++) {
            RES[i] = NUM[i];
            PARENT[i] = i;
            RANK[i] = 0;
        }

        for(vector<Operator>::iterator it = OP.begin(); it != OP.end(); ++it) {
            var r = compute(*it);
            if((*it).type == 3) {
                RES[Find((*it).ind)] = r;
            } else {
                Union((*it).ind, (*it).ind-1, r);
            }
        }

        fout<<RES[Find(1)];
    }

    return 0;
}