Cod sursa(job #199156)

Utilizator anna_bozianuBozianu Ana anna_bozianu Data 17 iulie 2008 08:49:01
Problema Barman Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.05 kb
#include<stdio.h>
long n,i,a[605],b[1205],*c,
pmin[605],pmax[605],sol,down[1205],up[1205],*st,*dr;
void citire();
void sortare();
void make_poz();
void solve();
void hd(long ic,long nc);
void sh(long i1,long i2);
long cost(long i1,long i2);
int main()
{
	citire();
	sortare();
	make_poz();
	for(i=0;i<n;i++)
	{ c=&b[i];
	  st=&down[i];
	  dr=&up[i];
	  solve();
	}
	freopen("barman.out","wt",stdout);
	printf("%ld",sol);
	return 0;
}
void citire()
{
	freopen("barman.in","rt",stdin);
	scanf("%ld",&n);
	for(i=1;i<=n;i++){scanf("%ld",&b[i]);a[i]=b[i];}
	for(i=1;i<=n;i++)b[i+n]=b[i];
	sol=1000000;
}
void sortare()
{
	for(i=n/2;i>=1;i--)hd(i,n);
	for(i=n;i>=1;i--){sh(1,i);hd(1,i-1);}
}
void make_poz()
{       long val,L,R,M;
	pmin[1]=1;
	for(i=2;i<=n;i++)pmin[i]=(a[i]==a[i-1])?pmin[i-1]:i;
	pmax[n]=n;
	for(i=n-1;i>=1;i--)pmax[i]=(a[i]==a[i+1])?pmax[i+1]:i;
	for(i=1;i<=n;i++)
	{ val=b[i];
	  if(val==a[1]){down[i]=pmin[1];up[i]=pmax[1];continue;}
	  if(val==a[n]){down[i]=pmin[n];up[i]=pmax[n];continue;}
	  L=1;R=n;
	  for(;;)
	  { M=(L+R)/2;
	    if(val<a[M]){R=M;continue;}
	    if(val>a[M]){L=M;continue;}
	    down[i]=pmin[M];up[i]=pmax[M];break;
	  }
	}
	for(i=1;i<=n;i++)
	{ down[i+n]=down[i];up[i+n]=up[i];}
}
void solve()
{   long L,R,sc=0,j,c1,c2,oc[605],r=n;
    for(j=1;j<=n;j++){ oc[j]=(c[j]==a[j])?1:0;r-=oc[j];}
    if(!r)sc=0;
    else
    { for(j=1;j<=n;j++)if(!oc[j])break;
      while(r)
      { L=st[j];R=dr[j];
	while(oc[L])L++;c1=cost(j,L);
	while(oc[R])R--;c2=cost(j,R);
	if(c1<c2){sc+=c1;oc[L]=1;j=L;}
	else     {sc+=c2;oc[R]=1;j=R;}
	r--;
      }
    }
    sol=(sc<sol)?sc:sol;
}
void hd(long ic,long nc)
{
	long is,is1;
	is=2*ic;is1=is+1;
	if(is>nc)return;
	if(is<nc)if(a[is]<a[is1])is=is1;
	if(a[ic]<a[is]){sh(is,ic);hd(is,nc);}
}
void sh(long i1,long i2)
{ long aux=a[i1];a[i1]=a[i2];a[i2]=aux;}
long cost(long i1,long i2)
{
	long j1,j2,ret1,ret2,ret;
	j1=(i1<i2)?i1:i2;
	j2=(i1>i2)?i1:i2;
	ret1=j2-j1;
	ret2=j1+n-j2;
	ret=(ret1<ret2)?ret1:ret2;
	ret+=20;
	return ret;
}