Cod sursa(job #2721920)

Utilizator Ilie_MityIlie Dumitru Ilie_Mity Data 12 martie 2021 14:16:14
Problema Bool Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 8.58 kb
//Ilie Dumitru
#include<cstdio>
#include<cstring>

struct nod
{
    char op, val;
    nod *lft, *rgt;
};

bool val[26];
char line[1005];
int length;

int parant(int i)
{
    int p=0;
    do
    {
        if(line[i]=='(')
            ++p;
        else if(line[i]==')')
            --p;
        ++i;
    }while(p);
    return i-1;
}

bool check(int i)
{
    bool ok=true, elem=false;
    while(ok)
    {
        while(line[i]==' ')
            ++i;
        if(line[i]=='(')
            i=parant(i);
        else if(line[i]=='N' && line[i+1]=='O')
            i+=3;
        else
        {
            if(!elem)
            {
                while(line[i]>='A' && line[i]<='Z')
                    ++i;
                elem=true;
            }
            else
            {
                if(line[i]=='A' && line[i+1]=='N')
                    return true;
                return false;
            }
        }
    }
    if(line[i]==' ' && line[i+1]=='A' && line[i+2]=='N')
        return true;
    return false;
}

nod* create(int &i)
{
    nod* rt0=0, *rt1=0, *auxrez=0;
    char op=0, neg=0;
    while(i<length)
    {
        if(line[i]==' ' || line[i]=='\n')
            ++i;
        else if(line[i]=='T' && line[i+1]=='R')
        {
            i+=4;
            if(op)
            {
                rt1=new nod;
                rt1->lft=rt1->rgt=0;
                if(neg)
                    rt1->val='f';
                else
                    rt1->val='t';
                neg=0;
                rt1->op=0;
                auxrez=new nod;
                auxrez->lft=rt0;
                auxrez->rgt=rt1;
                auxrez->op=op;
                op=0;
                rt0=auxrez;
                rt1=0;
            }
            else
            {
                rt0=new nod;
                rt0->lft=rt0->rgt=0;
                if(neg)
                    rt0->val='f';
                else
                    rt0->val='t';
                neg=0;
                rt0->op=0;
            }
        }
        else if(line[i]=='F' && line[i+1]=='A')
        {
            i+=5;
            if(op)
            {
                rt1=new nod;
                rt1->lft=rt1->rgt=0;
                if(neg)
                    rt1->val='t';
                else
                    rt1->val='f';
                neg=0;
                rt1->op=0;
                auxrez=new nod;
                auxrez->lft=rt0;
                auxrez->rgt=rt1;
                auxrez->op=op;
                op=0;
                rt0=auxrez;
                rt1=0;
            }
            else
            {
                rt0=new nod;
                rt0->lft=rt0->rgt=0;
                if(neg)
                    rt0->val='t';
                else
                    rt0->val='f';
                neg=0;
                rt0->op=0;
            }
        }
        else if(line[i]=='A' && line[i+1]=='N')
        {
            i+=3;
            op='a';
        }
        else if(line[i]=='N' && line[i+1]=='O')
        {
            i+=3;
            neg=1;
        }
        else if(line[i]=='O' && line[i+1]=='R')
        {
            i+=2;
            if(check(i))
            {
                rt1=create(i);
                auxrez=new nod;
                auxrez->lft=rt0;
                auxrez->rgt=rt1;
                auxrez->op='o';
                rt0=auxrez;
            }
            else
                op='o';
        }
        else if(line[i]=='(')
        {
            ++i;
            auxrez=create(i);
            if(op)
            {
                if(neg)
                {
                    rt1=new nod;
                    rt1->lft=auxrez;
                    rt1->rgt=0;
                    rt1->op='n';
                }
                else
                    rt1=auxrez;
                neg=0;
                auxrez=new nod;
                auxrez->lft=rt0;
                auxrez->rgt=rt1;
                auxrez->op=op;
                op=0;
                rt0=auxrez;
                rt1=0;
            }
            else
            {
                if(neg)
                {
                    rt0=new nod;
                    rt0->lft=auxrez;
                    rt0->rgt=0;
                    rt0->op='n';
                }
                else
                    rt0=auxrez;
                neg=0;
            }
        }
        else if(line[i]==')')
        {
            ++i;
            return rt0;
        }
        else
        {
            if(op)
            {
                rt1=new nod;
                if(neg)
                {
                    rt1->lft=new nod;
                    rt1->lft->lft=rt1->lft->rgt=0;
                    rt1->lft->val=line[i];
                    rt1->lft->op=0;
                    rt1->op='n';
                    rt1->rgt=0;
                }
                else
                {
                    rt1->lft=rt1->rgt=0;
                    rt1->val=line[i];
                    rt1->op=0;
                }
                neg=0;
                auxrez=new nod;
                auxrez->lft=rt0;
                auxrez->rgt=rt1;
                auxrez->op=op;
                rt0=auxrez;
                op=0;
            }
            else
            {
                rt0=new nod;
                if(neg)
                {
                    rt0->lft=new nod;
                    rt0->lft->lft=rt0->lft->rgt=0;
                    rt0->lft->val=line[i];
                    rt0->lft->op=0;
                    rt0->op='n';
                    rt0->rgt=0;
                }
                else
                {
                    rt0->lft=rt0->rgt=0;
                    rt0->val=line[i];
                    rt0->op=0;
                }
                neg=0;
            }
            ++i;
        }
    }
    return rt0;
}

bool eval(nod* rt)
{
    if(rt->op)
    {
        bool a, b;
        switch(rt->op)
        {
        case 'n':
            a=!eval(rt->lft);
            return a;
        case 'o':
            a=eval(rt->lft);
            b=eval(rt->rgt);
            return a||b;
        case 'a':
            a=eval(rt->lft);
            b=eval(rt->rgt);
            return a&&b;
        }
    }
    else
    {
        switch(rt->val)
        {
        case 't':
            return true;
        case 'f':
            return false;
        case 1:
            return true;
        case 0:
            return false;
        default:
            return val[rt->val-'A'];
        }
    }
    return 0;
}

char simplif(nod *&n)
{
    if(n->op)
    {
        char a, b;
        switch(n->op)
        {
        case 'n':
            a=simplif(n->lft);
            if(a<2)
            {
                n->lft=0;
                n->val=!a;
                n->op=0;
                return !a;
            }
            return 2;
        case 'o':
            a=simplif(n->lft);
            b=simplif(n->rgt);
            if(a==1 || b==1)
            {
                n->lft=n->rgt=0;
                n->val=1;
                n->op=0;
                return 1;
            }
            else if(a==0 && b==0)
            {
                n->lft=n->rgt=0;
                n->val=0;
                n->op=0;
                return 0;
            }
            return 2;
        case 'a':
            a=simplif(n->lft);
            b=simplif(n->rgt);
            if(a==1 && b==1)
            {
                n->lft=n->rgt=0;
                n->val=1;
                n->op=0;
                return 1;
            }
            else if(!a || !b)
            {
                n->lft=n->rgt=0;
                n->val=0;
                n->op=0;
                return 0;
            }
            return 2;
        }
    }
    switch(n->val)
    {
    case 't':
        return 1;
    case 'f':
        return 0;
    default:
        return 2;
    }
    return 2;
}

int main()
{
    nod *root=0;
    int N, i=0;
    char c;

    freopen("bool.in", "r", stdin);
    freopen("bool.out", "w", stdout);
    fgets(line, 1001, stdin);
    length=strlen(line);
    root=create(i);
    scanf("%i\n", &N);
    c=simplif(root);
    if(c<2)
        for(i=0;i<N;++i)
            printf("%i", c);
    else
        for(i=0;i<N;++i)
        {
            scanf("%c", &c);
            val[c-'A']^=true;
            printf("%i", eval(root));
        }
    fclose(stdin);
    fclose(stdout);
    return 0;
}