Cod sursa(job #2017112)

Utilizator caesar2001Stoica Alexandru caesar2001 Data 31 august 2017 12:24:36
Problema Bool Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.99 kb
#include <cstdio>
#include <map>
#include <cstring>
#include <string>

using namespace std;

FILE *in,*out;

const int nmax = 1000;

char c[nmax+3];

map <string,bool> m;

struct Symbol
{
    int tip;
    string semn;
    string val;
    int prio;
}v[1+nmax];

int n;

void parsare()
{
    int i = 0;
    while(c[i] != '\0')
    {
        int iplus = 1;
        if('A' <= c[i] && c[i] <= 'Z' && (c[i+1] < 'A' || c[i+1] > 'Z'))
        {
            v[++n].tip = 4;
            v[n].val = string(1,c[i]);
            m[v[n].val] = 0;
        }
        if(c[i] == '(')
           v[++n].tip = 1;
        if(c[i] == ')')
            v[++n].tip = 2;
        if(c[i] == 'N' && c[i+1] == 'O' && c[i+2] == 'T')
        {
            v[++n].tip = 4;
            v[n].val = "TRUE";
            v[++n].tip = 3;
            v[n].semn = "NOT";
            v[n].prio = 3;
            iplus = 3;
        }
        if(c[i] == 'A' && c[i+1] == 'N' && c[i+2] == 'D')
        {
            v[++n].tip = 3;
            v[n].semn = "AND";
            v[n].prio = 2;
            iplus = 3;
        }
        if(c[i] == 'O' && c[i+1] == 'R')
        {
            v[++n].tip = 3;
            v[n].semn = "OR";
            v[n].prio = 1;
            iplus = 2;
        }
        if(c[i] == 'T' && c[i+1] == 'R')
        {
            v[++n].tip = 4;
            v[n].val = "TRUE";
            iplus = 4;
        }
        if(c[i] == 'F' && c[i+1] == 'A')
        {
            v[++n].tip = 4;
            v[n].val = "FALSE";
            iplus = 5;
        }
        i += iplus;
    }
    m["TRUE"] = 1;
    m["FALSE"] = 0;

}

int jump[1+nmax][4],last[1+nmax][4];

void precalculate()
{
    for(int j = 1;j <= 3;j ++)
    {
        int level = 0;
        for(int i = 1;i <= n;i ++)
        {
            if(v[i].tip == 1)
                level ++;
            if(v[i].tip == 2)
            {
                level --;
                jump[i][j] = last[level][j];
            }
            if(v[i].tip == 3)
            {
                jump[i][j] = last[level][j];
                if(v[i].prio == j)
                    last[level][j] = i;
            }
            if(v[i].tip == 4)
                jump[i][j] = last[level][j];
        }
    }
}

int root,left[1+nmax],right[1+nmax];

int buildtree(int from,int to)
{
    if(from == to)
        return from;
    else
    {
        int node = jump[to][1];
        if(node == 0 || node < from)
            node = jump[to][2];
        if(node == 0 || node < from)
            node = jump[to][3];
        if(node == 0 || node < from)
            return buildtree(from+1,to-1);
        else
        {
            left[node] = buildtree(from,node-1);
            right[node] = buildtree(node+1,to);
            return node;
        }
    }
}

const int tmax = 100;
char k[tmax+3];

bool calculate(int node)
{
    if(v[node].tip == 4){
        //printf("%d -> %d\n",node,m[v[node].val]);
        return m[v[node].val];
    }
    else
    {
        //printf("%c\n",v[node].semn);
        if(v[node].semn == "NOT")
            return (1 - calculate(right[node]));
        if(v[node].semn == "AND")
            return calculate(left[node]) && calculate(right[node]);
        if(v[node].semn == "OR")
            return (calculate(left[node]) || calculate(right[node]));
    }

}

int main()
{
    in = fopen("bool.in","r");
    out = fopen("bool.out","w");
    fgets(c,nmax+3,in);
    parsare();
    precalculate();
    root = buildtree(1,n);
    int t;
    fscanf(in,"%d\n",&t);
    fgets(k,tmax+3,in);
    for(int i = 0;i < t;i ++)
    {
        m[string(1,k[i])] = 1 - m[string(1,k[i])];
        fprintf(out,"%d",calculate(root));
    }
    /*for(int i = 1;i <= n;i ++)
        printf("%d -> %d si %d\n",i,left[i],right[i]);
    for(int j = 1;j <= 3;j ++)
    {
        for(int i = 1;i <= n;i ++)
            printf("%d ",jump[i][j]);
        printf("\n");
    }*/
    return 0;
}