Cod sursa(job #2771641)

Utilizator Ilie_MityIlie Dumitru Ilie_Mity Data 28 august 2021 13:40:24
Problema Bool Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 6.38 kb
//Ilie Dumitru
#include<cstdio>
#include<cstring>
#define NMAX 1005
typedef long long ll;
FILE *f=fopen("bool.in", "r"), *g=fopen("bool.out", "w");

char expr[NMAX], simplifExpr[NMAX];
bool val[26];
int length;

class node
{
public:
    char op, val;
    node* left, *right;
    node() : op(0), val(0), left(0), right(0) {}
    node(char _op, char _val, node* l=0, node* r=0) : op(_op), val(_val), left(l), right(r) {}
    ~node() {if(this->left) delete this->left; if(this->right) delete this->right;}
    bool eval()
    {
        switch(this->op)
        {
        case '&':
            return this->left->eval() && this->right->eval();
        case '|':
            return this->left->eval() || this->right->eval();
        case '!':
            return !this->right->eval();
        case 0:
        {
            if(this->val>1)
                return ::val[this->val-'A'];
            return this->val;
        }
        }
        return 0;
    }
    char simplif()
    {
        switch(this->op)
        {
        case '&':
        {
            char a=this->left->simplif(), b=this->right->simplif();
            if(!a || !b)
            {
                this->op=0;
                this->val=0;
                delete this->left;
                delete this->right;
                this->left=this->right=0;
                return 0;
            }
            if(a==1 && b==1)
            {
                this->op=0;
                this->val=1;
                delete this->left;
                delete this->right;
                this->left=this->right=0;
                return 1;
            }
            return 2;
        }
        case '|':
        {
            char a=this->left->simplif(), b=this->right->simplif();
            if(a==1 || b==1)
            {
                this->op=0;
                this->val=1;
                delete this->left;
                delete this->right;
                this->left=this->right=0;
                return 1;
            }
            if(!a && !b)
            {
                this->op=0;
                this->val=0;
                delete this->left;
                delete this->right;
                this->left=this->right=0;
                return 0;
            }
            return 2;
        }
        case '!':
        {
            char a=this->right->simplif();
            if(!a)
            {
                this->op=0;
                this->val=1;
                delete this->right;
                this->right=0;
                return 1;
            }
            if(a==1)
            {
                this->op=0;
                this->val=0;
                delete this->right;
                this->right=0;
                return 0;
            }
            return 2;
        }
        case 0:
        {
            if(!this->val)
                return 0;
            if(this->val==1)
                return 1;
            return 2;
        }
        }
        return 2;
    }
    void printExpr()
    {
        switch(this->op)
        {
        case '!':
            printf("!(");
            this->right->printExpr();
            printf(")");
            break;
        case '&':
            printf("(");
            this->left->printExpr();
            printf(")&(");
            this->right->printExpr();
            printf(")");
            break;
        case '|':
            printf("(");
            this->left->printExpr();
            printf(")|(");
            this->right->printExpr();
            printf(")");
            break;
        case 0:
            if(this->val>1)
                printf("%c", this->val);
            else
                printf("%d", this->val);
        }
    }
};

//evaluate [start, end)
void createTree(node*& root, int start, int end, int* priorities)
{
    if(end-start>1)
    {
        int min=2e9, posmin=-1, i;
        for(i=start;i<end;++i)
            if(priorities[i] && priorities[i]<min)
                min=priorities[i], posmin=i;
        if(posmin!=-1)
        {
            root=new node(simplifExpr[posmin], 0);
            if(simplifExpr[posmin]!='!')
                createTree(root->left, start, posmin, priorities);
            createTree(root->right, posmin+1, end, priorities);
        }
        else
        {
            for(i=start;i<end && simplifExpr[i]=='(';++i);
            root=new node(0, simplifExpr[i]);
        }
    }
    else root=new node(0, simplifExpr[start]);
}

node* createTree()
{
    int* priorities=new int[length], i, prnt=0;
    node* root=0;
    for(i=0;i<length;++i)
    {
        priorities[i]=0;
        if(simplifExpr[i]=='(')
            ++prnt;
        else if(simplifExpr[i]==')')
            --prnt;
        else if(simplifExpr[i]=='!')
            priorities[i]=3+prnt*4;
        else if(simplifExpr[i]=='&')
            priorities[i]=2+prnt*4;
        else if(simplifExpr[i]=='|')
            priorities[i]=1+prnt*4;
    }
    createTree(root, 0, length, priorities);
    delete[] priorities;
    return root;
}

void simplif()
{
    for(int i=0;expr[i];++i)
        if(expr[i]!=' ')
        {
            if(expr[i]=='(' || expr[i]==')')
                simplifExpr[length++]=expr[i];
            else
            {
                if(expr[i]=='N' && expr[i+1]=='O')
                    simplifExpr[length++]='!', i+=2;
                else if(expr[i]=='O' && expr[i+1]=='R')
                    simplifExpr[length++]='|', i+=1;
                else if(expr[i]=='A' && expr[i+1]=='N')
                    simplifExpr[length++]='&', i+=2;
                else if(expr[i]=='T' && expr[i+1]=='R')
                    simplifExpr[length++]=1, i+=3;
                else if(expr[i]=='F' && expr[i+1]=='A')
                    simplifExpr[length++]=0, i+=4;
                else
                    simplifExpr[length++]=expr[i];
            }
        }
    simplifExpr[length]=0;
}

int main()
{
    fgets(expr, NMAX, f);
    {int x=strlen(expr);if(expr[x-1]=='\n')expr[x-1]=0;}
    simplif();
    node* tree=createTree();
    tree->simplif();
    //tree->printExpr();
    int _;
    char c;
    fscanf(f, "%d\n", &_);
    while(_--)
    {
        fscanf(f, "%c", &c);
        val[c-'A']^=1;
        fprintf(g, "%d", tree->eval());
    }
    delete tree;
    fclose(f);
    fclose(g);
    return 0;
}