Cod sursa(job #2663683)

Utilizator Robert.BrindeaBrindea Robert Robert.Brindea Data 27 octombrie 2020 00:31:24
Problema Bool Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.82 kb
#include <iostream>
#include <fstream>
#include <cstring>

using namespace std;

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

const int MAXN = 1010;

struct Nod
{
    char op{'#'}, nume{'#'};
    int val{-1};
    bool invers{0};
    Nod *left{0}, *right{0};
};

char init[MAXN], operatori[4][4] = {"RO ", "DNA", "TON"};
int val[30], n;
Nod *a;

Nod* construire(int l, int r)
{
    for(int nivel = 0; nivel < 2; nivel++)
    {
        int depth = 0;
        for(int i = r; i >= l; i--)
        {
            if(init[i] == ')') depth++;
            else if(init[i] == '(') depth--;
            else if(depth == 0 && init[i] == operatori[nivel][0] && init[i-1] == operatori[nivel][1] && init[i-2] == operatori[nivel][2])
            {
                Nod* nou = new Nod;
                nou -> left = construire(l, i-4 + (init[i-2]==' '));
                nou -> right = construire(i+2, r);
                if(init[i] == 'R')
                    nou -> op = '|';
                if(init[i] == 'D')
                    nou -> op = '&';

                return nou;
            }
        }
    }

    if(init[l] == '(' && init[r] == ')')
        return construire(l+1, r-1);

    bool vnot = 0;
    if(init[l] == 'N' && init[l+1] == 'O' && init[l+2] == 'T')
    {
        l += 4;
        vnot = 1;
    }
    Nod* nou = new Nod;

    if(init[l] == 'T' && init[l+1] == 'R' && init[l+2] == 'U' && init[l+3] == 'E')
        nou -> val = 1^vnot;
    else if(init[l] == 'F' && init[l+1] == 'A' && init[l+2] == 'L' && init[l+3] == 'S' && init[l+4] == 'E')
        nou -> val = 0^vnot;
    else
         nou -> nume = init[l];

    nou -> invers = vnot;
    return nou;
}

/*
void parcurgere(Nod* crt, int nivel)
{
    if(crt == nullptr) return;

    for(int i = 0; i < nivel; i++)
        cout << "\t";
    if(crt -> invers == 1)
        cout << "~";
    if(crt->val != -1)
        cout << crt -> val << "\n";
    else if(crt->op != '#')
        cout << crt -> op << "\n";
    else cout << crt -> nume << "\n";
    parcurgere(crt->left, nivel+1);
    parcurgere(crt->right, nivel+1);

}
*/

int evaluare(Nod* crt)
{
    if(crt -> val != -1)
        return crt -> val;
    if(crt -> nume != '#')
        return (val[crt->nume - 'A']) ^ crt -> invers;
    else
    {
        int a = evaluare(crt -> left), b = evaluare(crt -> right);
        switch(crt->op)
        {
            case '|':
                return a|b;
            case '&':
                return a&b;
        }
    }
}

int main()
{
    fin.getline(init, MAXN);
    a = construire(0, strlen(init)-1);
    //parcurgere(a, 0);
    fin >> n;
    fin.get();
    char x;
    for(int i = 0; i < n; i++)
    {
        x = fin.get();
        val[x-'A'] ^= 1;
        fout << evaluare(a);
    }
    return 0;
}