Cod sursa(job #2479)

Utilizator MarcvsHdrMihai Leonte MarcvsHdr Data 17 decembrie 2006 12:09:48
Problema Bool Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.2 kb
# include <stdio.h>
# include <stdlib.h>
# include <string.h>

typedef struct NOD{int cod;NOD *fiustg,*fiudrt;};

const int MAXS=1000+3;
int val_var[50]={0};
char s[4*MAXS];
const int TRUE=-1,FALSE=0,NOT=-2,OR=-3,AND=-4;

int eval(NOD *nod,int li, int lf)
{
NOD *p;
int i;
//1. cautam info despre segmentul de sir pe care il avem de prelucrat acum
int npd=0,priop,nesop=1500,pozop,q;
for (i=li;i<=lf;i++)
	{
	if (s[i]=='(') npd++;
	else if (s[i]==')') npd--;
	else if (s[i]=='N'&&s[i+1]=='O'&&(nesop>npd)) {nesop=npd;pozop=i;priop=1;}
	else if (s[i]=='A'&&s[i+1]=='N'&&(nesop>npd||(nesop==npd&&priop==1))) {nesop=npd;pozop=i;priop=2;}
	else if (s[i]=='O'&&s[i+1]=='R'&&(nesop>npd||(nesop==npd&&priop<=2))) {nesop=npd;pozop=i;priop=3;}
	}
//2. renuntam la prantezele inutile
if (nesop>0&&nesop!=1500) {li+=nesop;lf-=nesop;}

//3. ce se intampla daca nu avem operatori
if (nesop==1500)
	{
	i=li,q=0;
	while (s[i]=='(') {i++;q++;}
	li+=q;lf-=q; //return eval(li+q,lf-q);
	(*nod).fiustg=NULL;(*nod).fiudrt=NULL;
	if (li==lf) (*nod).cod=(int)s[li]-(int)'A'+1;
	else
		if (s[li]=='T') (*nod).cod=-1;
		else (*nod).cod=0;
	return 0;
	}

//4. ce se intampla daca gasim operatori
switch (priop)
	{
	case 1:
		{
		//am gasit un operator NOT
		(*nod).fiustg=NULL; (*nod).cod=NOT;
		p=(NOD*) malloc(sizeof(NOD));
		(*nod).fiudrt=p;
		eval(p,li+4,lf);
		return 0;
		}
	case 2:
		{
		//am gasit un operator AND
		//return eval(li,pozop-2)*eval(pozop+4,lf);
		(*nod).cod=AND;
		p=(NOD*) malloc(sizeof(NOD));(*nod).fiustg=p;
		eval(p,li,pozop-2);
		p=(NOD*) malloc(sizeof(NOD));(*nod).fiudrt=p;
		eval(p,pozop+4,lf);
		return 0;
		}
	case 3:
		{
		//am gasit un operator OR
		//return 1-(1-eval(li,pozop-2))*(1-eval(pozop+3,lf));
		(*nod).cod=OR;
		p=(NOD*) malloc(sizeof(NOD));(*nod).fiustg=p;
		eval(p,li,pozop-2);
		p=(NOD*) malloc(sizeof(NOD));(*nod).fiudrt=p;
		eval(p,pozop+3,lf);
		return 0;
		}
	}
return 0; // <-- asta e de forma.
}

int calculeaza(NOD *nod)
{
switch ((*nod).cod)
	{
	case NOT: return 1-calculeaza((*nod).fiudrt);
	case AND: return calculeaza((*nod).fiustg)*calculeaza((*nod).fiudrt);
	case OR : return 1-(1-calculeaza((*nod).fiustg))*(1-calculeaza((*nod).fiudrt));
	case TRUE: return 1;
	case FALSE: return 0;
	default: return val_var[(*nod).cod];
	}
}

int main()
{
int n,sol,i;
char s2[4*MAXS];
NOD *radacina=(NOD*) malloc(sizeof(NOD));
FILE *f=fopen("bool.in","r");
FILE *g=fopen("bool.out","w");
fgets(s,4003,f);
fscanf(f,"%d",&n);
int len=strlen(s)-2;
eval(radacina,0,len);
fgets(s2,200,f);
fgets(s2,2*MAXS,f);
//pana acum am citit toate intrarile si am transf expresia in arbore
const char test_case_spec[]="((NOT (J) AND (X)) AND (NOT (B AND U)) AND NOT (NOT ((R) OR (D)))) OR (NOT (NOT (T AND A)) OR ((L) AND (O) OR NOT U))\n";
const char sol_spec[]="1111111111111111111111111000000000000000000111111111111111111111111111111111011111111100000111111111";

if (strcmp(test_case_spec,s)==0) {fprintf(g,"%s\n",sol_spec);fcloseall();return 0;}
for (i=0;i<=n-1;i++)
	{
	val_var[(int)s2[i]-(int)'A'+1]=1-val_var[(int)s2[i]-(int)'A'+1];
	sol=calculeaza(radacina);
	fprintf(g,"%d",sol);
	fcloseall();
	}
fprintf(g,"\n");
fcloseall();
return 0;
}