Cod sursa(job #254857)

Utilizator stocarulCosmin-Mihai Tutunaru stocarul Data 7 februarie 2009 21:06:32
Problema Episoade Scor 50
Compilator c Status done
Runda Arhiva de probleme Marime 3.57 kb
#include<stdio.h>
#define infile "episoade.in"
#define outfile "episoade.out"
#define nmax 105
#define lmax 1001
int p[nmax]; //vectorul de conditii obligatorii
int m[nmax][nmax]; //matricea de conditii partiale...(m[i][0] - numarul lor....m[i][1] - numarul numarul minim pt cate trebuie sa fie inainte;)))
char v[lmax]; //vectorul in care citim sirul
int x[nmax]; //vectorul in care citim pt fiecare test in ce ordine vrea sa citeasca
int t,n; //numarul de teste, respectiv numarul de episoade

//preprocesam matricea de prioritati
void preprocesare(int p[nmax], int m[nmax][nmax], char v[lmax], int n)
	{
	int i=0,j,e,ok,obl;
	int sp[lmax]; sp[0]=1; sp[1]=0; int nrp=0; //stiva pt numarul de paranteze deschise (implicit avem o pranteza cu 0 obligatorii.....)...respectiv numarul de chestii obligatorii din fiecare paranteza, si numarul de chestii obligatorii totale (minus cele dupa ce inchidem parantezele)
	int se[nmax]; se[0]=0; //stiva de episoade......
	while(v[i]!='\n'&&v[i]) //cat timp avem de procesat ;))
		{
		if(v[i]=='(') { sp[++sp[0]]=0; i++; } //deschidem o paranteza, nu are nicio chestie obligatorie in ea
		if(v[i]==')') { nrp-=sp[sp[0]]; sp[0]--; i++; } //inchidem o paranteza...scoatem din chestiile obligatorii globale....pe cele care sunt in aceasta paranteza
		if(v[i]>='0'&&v[i]<='9') //avem episod
			{
			if(i>0&&v[i-1]=='>'&&v[i-2]>='0'&&v[i-2]<='9') ok=1; else ok=0; //daca are chestie obligatorie sau nu cu un alt episod
			if(v[i-1]=='>') obl=1; else obl=0;
			se[0]++; se[se[0]]=0; //trebuie sa facem loc unui nr in stiva;))
			while(v[i]>='0'&&v[i]<='9') se[se[0]]=se[se[0]]*10+v[i++]-'0'; //refacem numarul din caractere
			
			if(ok) p[se[se[0]]]=se[se[0]-1]; //trebuei sa apara obligatoriu dupa episodul anterior
			else //nu trebuie sa apara obligatoriu dupa unul singur....insa trebuie sa aiba in stanga lui un anumit numar de episoade dintre ele din stiva ;))
				{
				e=se[se[0]]; //episodul nostru ;))
				m[e][0]=se[0]; //numarul de episoade din stiva ;))
				if(obl) m[e][1]=nrp; //daca are chestie obligatorie
				else m[e][1]=nrp-sp[sp[0]]; //cate episoade din cele din stiva trebuie sa se afle inaintea lui ;))
				for(j=1;j<=se[0];j++) m[e][j+1]=se[j]; //copiem episoadele din stiva in matricea pt conditii partiale pt acest episod
				}
			}
		if(v[i]=='>') { sp[sp[0]]++; nrp++; i++; } //am gasit o chestie obligatorie...o salvam ;))
		else i++; //daca e altceva nu ne intereseaza;))
		}
	}

int cauta(int v[nmax], int x)
	{
	int i;
	for(i=1;i<=v[1];i++)
		if(v[i+1]==x) return 1; //l-am gasit ;))
	return 0; //daca am ajuns aici, inseamna k nu l-am gasit ;))
	}

int verifica(int m[nmax][nmax], int p[nmax], int x[nmax], int n)
	{
	int i,j,k;
	for(i=1;i<=n;i++)
		{
		if(p[x[i]]) //inseamna ca x[i] are o prioritate
			{ if(x[i-1]!=p[x[i]]) return 0; } //nu se respecta prioritatea...deci sir incorect
		else //vedem daca avem prioritati partiale ;))
			{
			for(k=0,j=1;k<m[x[i]][1]&&j<i;j++) //cat timp nu au fost gasite episoadele anterioare minime
				if(cauta(m[x[i]],x[j])) k++; //am gasit unul din ele...marcam
			if(k<m[x[i]][1]) return 0; //nu au fost gasite suficiente
			}
		}
	return 1; //inseamna ca avem un sir corect
	}

int main()
{
int i;
freopen(infile,"r",stdin);
freopen(outfile,"w",stdout);

fgets(v,lmax,stdin); //citim sirul
scanf("%d %d\n",&t,&n);
preprocesare(p,m,v,n); //preprocesam
while(t--) //avem de verificat siruri
	{
	for(i=1;i<=n;i++) scanf("%d",&x[i]); //citim ordinea in care vrea sa citeasca baiatu
	printf("%d\n",verifica(m,p,x,n));
	}

fclose(stdin);
fclose(stdout);
return 0;
}