Cod sursa(job #482487)

Utilizator razvi9Jurca Razvan razvi9 Data 3 septembrie 2010 17:00:35
Problema Bool Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.97 kb
#include <fstream>
#include <vector>
#include <cstring>
#include <stack>
using namespace std;

struct node
{
	enum Type
	{
		End,
		Or,
		And,
		Not
	};

	bool value;
	Type type;
	node *left, *right;

	node() { left = right = NULL; type = End; value = false; }

	node(bool val) { left = right = NULL; type = End; value = val;}

	void compute()
	{
		if (left != NULL)
			left->compute();
		if (right != NULL)
			right->compute();

		switch(type)
		{
			case node::And:
				value = (left->value) && (right->value);
				break;
			case node::Not:
				value = !(left->value);
				break;
			case node::Or:
				value = (left->value) || (right->value);
				break;
		}
	}
};

node* parse(char *&s);

vector<node*> allocated;
node Vars[26];
node False, True(true);
char str[10000];

int main()
{
	ifstream cin("bool.in");
	ofstream cout("bool.out");
	
	cin.getline(str, 9999);

	char *p = str;
	node* root = parse(p);

	int n;
	cin >> n;
	cin >> str;
	for(int i=0;i<n;++i)
	{
		Vars[str[i]-'A'].value = !Vars[str[i]-'A'].value;
		root->compute();
		cout << (root->value ? '1' : '0');
	}

	for(vector<node*>::iterator it = allocated.begin(); it != allocated.end(); ++ it)
		delete (*it);

	return 0;
}

inline bool startsWith(char *a, const char *b)
{
	int n=strlen(b);
	for(int i=0;i<n;++i)
		if(a[i] != b[i])
			return false;

	return true;
}

inline node* Or(node *a, node *b)
{
	node *t = new node;
	allocated.push_back(t);
	t->left = a;
	t->right = b;
	t->type = node::Or;
	return t;
}

inline node* And(node *a, node *b)
{
	node *t = new node;
	allocated.push_back(t);
	t->left = a;
	t->right = b;
	t->type = node::And;
	return t;
}

inline node* Not(node *a)
{
	node *t = new node;
	allocated.push_back(t);
	t->left = a;
	t->right = NULL;
	t->type = node::Not;
	return t;
}

inline node* Var(char c)
{
	return &Vars[c-'A'];
}

node* parse(char *&s)
{
	stack<node *> nodes;
	bool And = false;
	bool Not = false;
	node *a, *b;

	while(s[0])
	{
		while(s[0] == ' ' || s[0] == '\n')
			++ s;
		if(!s[0])
			break;
	
		if (s[0] == '(')
		{
			++ s;

			b = parse(s);
			if (Not)
				b = ::Not(b);
			if(And)
			{
				a = nodes.top(); nodes.pop();
				b = ::And(a, b);
			}
			nodes.push(b);

			++ s;
			Not = And = false;
		}
		else if (s[0] == ')')
			break;
		else if (startsWith(s, "NOT"))
			Not = true,
			s += 3;
		else if (startsWith(s, "OR"))
			s += 2;
		else if (startsWith(s, "AND"))
			s += 3,
			And = true;
		else
		{
			if (startsWith(s, "TRUE"))
				b = &True,
				s += 4;
			else if (startsWith(s, "FALSE"))
				b = &False,
				s += 5;
			else
				b = ::Var(s[0]), ++ s;

			if (Not)
				b = ::Not(b);
			if(And)
			{
				a = nodes.top(); nodes.pop();
				b = ::And(a, b);
			}
			nodes.push(b);
			Not = And = false;
		}
	}

	b = nodes.top(); nodes.pop();
	while(!nodes.empty())
		b = ::Or(nodes.top(), b),
		nodes.pop();

	return b;
}