Cod sursa(job #382250)

Utilizator petroMilut Petronela petro Data 13 ianuarie 2010 10:22:49
Problema Secv Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.57 kb
#include<stdio.h>
#define M 5000

long v[M],w[M],min[M];
int l[M],n,m=0;

int verif(int k)
{
	int i;
	for(i=1;i<=m;++i)
		if(w[i]==v[k]) return 0;
	return 1;
}

void cit()
{
	freopen("secv.in","r",stdin);
	
	fscanf(stdin,"%d",&n);
	int i;
	
	for(i=1;i<=n;++i)
	{
		fscanf(stdin,"%ld",&v[i]);
		if (verif(i)) w[++m]=v[i];
	}
	
	fclose(stdin);
}

int poz(int i,int j)
{
	int p,q;
	long x;
	x=w[i];
	p=i;
	q=j;
	
	while(p<q)
	{
		while(p<q && x<w[q])
			q--;
		w[p]=w[q];
		while(p<q && x>w[p])
			p++;
		w[q]=w[p];
	}
	w[p]=x;
	return p;
}
void quick(int i, int j)
{
	if(i<j) {int mijl=poz(i,j);
		     if(i<mijl) quick(i,mijl-1);
	         if(j>mijl) quick(mijl+1,j);}
}

void minim()
{
	int i;
	for(i=1;i<=n;++i)
		min[i]=w[m]+1;
}

int pd()
{
	int mm,i,k,ok,j,poz[M];
	mm=m;
	for(i=1;i<=n;++i)
		if(v[i]==w[m]) l[i]=1;
	
	mm--;
	while(mm)
	{
		k=0;
		for(i=1;i<=n;++i)
			if(v[i]==w[mm]) {l[i]=1;poz[++k]=i;}
		
		ok=0;
		for(i=1;i<=k;++i)
			for(j=poz[i];j<=n;++j)
				if(v[j]==w[mm+1]) {l[poz[i]]=l[j]+1;ok=1;
								  if(j-poz[i]+1<min[poz[i]]) min[poz[i]]=j-poz[i]+1;}	
		if(ok==0) return 0;
		mm--;
	}
	return 1;
}

int suma()
{
	int i,j,s;
	for(i=n;i>=1;i--)
		if(l[i]==m) {s=min[i];break;}
	
	m--;
	while(m!=1)
	{
		for(j=i;j<=n;j++)
			if(l[j]==m) {s=s+(min[j]-1); break;}
		i=j;
		m--;
	}
	return s;
}
	
int main()
{
	FILE *g=fopen("secv.out","w");
	cit();
	quick(1,m);
	minim();
		
	if(pd()==0) fprintf(g,"-1\n");
	else fprintf(g,"%d\n",suma());
		
	fclose(g);
	return 0;
}