Cod sursa(job #482462)

Utilizator razvi9Jurca Razvan razvi9 Data 3 septembrie 2010 16:21:41
Problema Bool Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.62 kb
#include <fstream>
#include <vector>
#include <cstring>
#include <stack>
#pragma pack(1)
using namespace std;

struct node
{
	bool value;
	char type;
	node *left, *right;

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

	enum Types
	{
		End,
		Or,
		And,
		Not
	};


	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->left || right->value;
				break;
		}
	}
};

node* parse(char *&s);

vector<node*> allocated;
node Vars[26];
char str[2000];

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

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

	int n;
	cin >> n;
	cin.getline(str, 2000);
	cin.getline(str, 2000);
	for(int i=0;i<n;++i)
	{
		Vars[str[i]-'A'].value ^= 1;
		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->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;
	
		if (s[0] == '(')
		{
			++ s;
			if (not)
				nodes.push(::not(parse(s)));
			else
				nodes.push(parse(s));

			if(and)
			{
				b = nodes.top(); nodes.pop();
				a = nodes.top(); nodes.pop();
				nodes.push(::and(a, 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
			nodes.push(::Var(s[0])),
			++ s;
	}

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

	return b;
}