Cod sursa(job #1723101)

Utilizator GabiTulbaGabi Tulba-Lecu GabiTulba Data 29 iunie 2016 18:05:24
Problema Bool Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.78 kb
//Problema Bool infoarena
//Gabi Tulba-Lecu
#include <cstdio>
#include <algorithm>
#define DimensiuneMaximaFisier 6000000
using namespace std;
char Fisier[DimensiuneMaximaFisier],Caracter,Coada[1005]={},Stiva[1005];
int NumarDeSchimabri,Pozitie=0,DimensiuneStiva=0,DimensiuneCoada=0,DimensiuneSolutie=0;
bool ValoriVariabile[30]={},Solutie[1005];
/*Vectorul Coada este expresia transformata in scriere poloneza inversa
Vectorul Stiva este un vector intermediar ce retine doar operatori,respectiv paranteze (vezi Shunting-yard algorithm)
Vectorul Fisier este folosit pentru parsarea(citirea) fisierului de intrare
Variabila Pozitie indica pozitia in vectorul Fisier
Vectorul Solutie este o stiva prin care vom afla valoarea finala e expresiei date(transformata in scriere poloneza inversa)
Vectorul ValoriVariabile reprezinta valoarea de adevar pentru fiecare litera (A..Z)
*/
void CitesteCaracter(char &Caracter)
{
    while(Fisier[Pozitie]<'A'||Fisier[Pozitie]>'Z')
    {
        if(Fisier[Pozitie]=='('||Fisier[Pozitie]==')')
        {
            Caracter=Fisier[Pozitie++];
            return;
        }

        Pozitie++;
    }

    Caracter=Fisier[Pozitie++];
}

void CitesteNumar(int &Numar)
{
    Numar=0;

    while(Fisier[Pozitie]<'0'||Fisier[Pozitie]>'9')
        Pozitie++;

    while(Fisier[Pozitie]>='0'&&Fisier[Pozitie]<='9')
        Numar=Numar*10+Fisier[Pozitie++]-'0';
}

void AdaugaInCoada(char Caracter)
{
	Coada[++DimensiuneCoada]=Caracter;
}

char VarfulStivei()
{
	return Stiva[DimensiuneStiva];
}/*Returneaza elementul din varful stivei*/

void AdaugaInStiva(char Caracter)
{
	Stiva[++DimensiuneStiva]=Caracter;
}

void AdaugaInSolutie(int Numar)
{
	Solutie[++DimensiuneSolutie]=Numar;
}

void EliminaDinStiva()
{
	DimensiuneStiva--;
}

void ExecutaOperatorul(char Operator)
{
	if(Operator=='!')
		Solutie[DimensiuneSolutie]=!Solutie[DimensiuneSolutie];

	else if(Operator=='|')
		Solutie[DimensiuneSolutie-1]|=Solutie[DimensiuneSolutie],DimensiuneSolutie--;

	else if(Operator=='&')
		Solutie[DimensiuneSolutie-1]&=Solutie[DimensiuneSolutie],DimensiuneSolutie--;
}//va evectua operatia respectiva pentru elementele din stiva Solutie (!,&,|)

bool RezolvaExpresia()
{
	DimensiuneSolutie=0;
	int CoadaPozitie=1;

	for(int CoadaPozitie=1;CoadaPozitie<=DimensiuneCoada;CoadaPozitie++)
	{
		if(Coada[CoadaPozitie]>='A'&&Coada[CoadaPozitie]<='Z')
			AdaugaInSolutie(ValoriVariabile[Coada[CoadaPozitie]-'A'+1]);

		else if(Coada[CoadaPozitie]=='1')
			AdaugaInSolutie(1);

		else if (Coada[CoadaPozitie]=='0')
			AdaugaInSolutie(0);

		else ExecutaOperatorul(Coada[CoadaPozitie]);
	}

	if(Solutie[1]==0)
		return false;

	else return true;
}

int main()
{
    freopen("bool.in","r",stdin);
    freopen("bool.out","w",stdout); 
    fread(Fisier,1,DimensiuneMaximaFisier,stdin);

	while(Fisier[Pozitie]!='\n')
	{
		CitesteCaracter(Caracter);

		if(Caracter>='A'&&Caracter<='Z'&&(Fisier[Pozitie]==' '||Fisier[Pozitie]==')'||Fisier[Pozitie]=='\n'))
			AdaugaInCoada(Caracter);//Se adauga variabila in coada

		else if(Caracter=='T')
			AdaugaInCoada('1'),Pozitie+=3;//TRUE are valoarea constanta si egala cu 1

		else if(Caracter=='F')
			AdaugaInCoada('0'),Pozitie+=4;//FALSE are valoarea constanta si egala cu 0

		else if(Caracter=='N')//Prioritate Maxima. Se executa primul
		{
			if(VarfulStivei()=='!')
				EliminaDinStiva();//Dubla negatie

			else
				AdaugaInStiva('!');

			Pozitie+=2;
		}
		else if(Caracter=='O')// OR are prioritate minima. Se va efectua dupa AND si NOT
		{
			while(VarfulStivei()=='&'||VarfulStivei()=='|'||VarfulStivei()=='!')
			{
				AdaugaInCoada(VarfulStivei());
				EliminaDinStiva();
			}

			AdaugaInStiva('|');
			Pozitie++;
		}
		else if(Caracter=='A')// OR are prioritate medie. Se va efectua dupa NOT si inainte de OR
		{
			while(VarfulStivei()=='&'||VarfulStivei()=='!')
			{
				AdaugaInCoada(VarfulStivei());
				EliminaDinStiva();
			}

			AdaugaInStiva('&');
			Pozitie+=2;
		}
		else if(Caracter=='(')
			AdaugaInStiva('(');//Se deschide o paranteza in Stiva

		else if(Caracter==')')
		{
			while(VarfulStivei()!='(')//Se adauga in coada toti opertorii din paranteza
			{
				AdaugaInCoada(VarfulStivei());
				EliminaDinStiva();
			}

			EliminaDinStiva();//Se sterge paranteza din stiva
		}

	}

	while(DimensiuneStiva>0)//Se adauga restul oreatorilor la sfarsitul cozii
	{
		AdaugaInCoada(VarfulStivei());
		EliminaDinStiva();
	}

	CitesteNumar(NumarDeSchimabri);

	for(int i=1;i<=NumarDeSchimabri;i++)
	{
		CitesteCaracter(Caracter);
		ValoriVariabile[Caracter-'A'+1]=!ValoriVariabile[Caracter-'A'+1];//Se schimba valoarea de adevar a variabilei
		
		if(RezolvaExpresia())
			printf("1");

		else printf("0");
	}

    return 0;
}