Cod sursa(job #366082)

Utilizator Magnuscont cu nume gresit sau fals Magnus Data 20 noiembrie 2009 22:21:40
Problema Barbar Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.82 kb
#include <stdio.h>

int v[101][101],dr[2][1001],w[2][1001],z,d,lee[2][1001],o[4],u[4];
int n,i,j,l,r,nx,ny,x,y,m;

void firewall(int a)
{
	int l2=0,r2=d;
	while ((v[dr[0][l2+1]][dr[1][l2+1]]>=1-a)&&(l2<r2))
	{
		++l2;
		for (i=0;i<4;i++)
		{
			nx=dr[0][l2]+o[i];
			ny=dr[1][l2]+u[i];
			if ((0<nx)&&(nx<n+1)&&(ny>0)&&(ny<m+1)&&(v[nx][ny]==0))
			{
			 ++r2;
			 dr[0][r2]=nx;
			 dr[1][r2]=ny;
			 v[nx][ny]=v[dr[0][l2]][dr[1][l2]]-1;
			}
		}
	}
}

int path()
{
	l=0;
	r=1;
	while (l<r)
	{
		++l;
		for (i=0;i<4;i++)
		{
			nx=lee[0][l]+o[i];
			ny=lee[1][l]+u[i];
			if ((0<nx)&&(nx<n+1)&&(ny>0)&&(ny<m+1)&&(v[nx][ny]==0))
			{
			 ++r;
			 lee[0][r]=nx;
			 lee[1][r]=ny;
			 v[nx][ny]=v[lee[0][l]][lee[1][l]]+1;
			}
		}
	}
	return v[x][y];
}

void init()
{
	for (i=1;i<n+1;i++)
		for (j=1;j<m+1;j++)
			v[i][j]=0;
	for (i=1;i<d+1;i++) v[dr[0][i]][dr[1][i]]=-1;
	for (i=1;i<z+1;i++) v[w[0][i]][w[1][i]]=-1;
}

int cautbin()
{
    int lo, hi, mid, last = 0;

    for (lo = 1, hi = m*n/3; lo <= hi; )
    {
	mid = lo + (hi-lo) / 2;
	firewall(mid);
	if (path()>0) last = mid, lo = mid+1;
	else hi = mid-1;
	init();
    }
    return last;
}

int main()
{
	FILE *f;
	char str[1003];
	f=fopen("barbar.in","r");
	freopen("barbar.out","w",stdout);
	o[0]=1;o[1]=-1;u[2]=1;u[3]=-1;
	fscanf(f,"%d%d\n",&n,&m);
	for (i=1;i<n+1;i++)
	{
		fgets(str,1003,f);
		for (j=0;j<m;j++)
		{
		 if (str[j]=='*')
		 {
			v[i][j+1]=-1;
			++z;
			w[0][z]=i;
			w[1][z]=j+1;
		 }
		 else if (str[j]=='D')
		 {
			v[i][j+1]=-1;
			++d;
			dr[0][d]=i;
			dr[1][d]=j+1;
		 }
		 else if (str[j]=='I')
		 {
		  lee[0][1]=i;
		  lee[1][1]=j+1;
		  v[i][j+1]=1;
		 }
		 else if (str[j]=='O')
		 {
		  x=i;
		  y=j+1;
		 }
		}
	}
	int a=cautbin();
	printf("%d",a);
	return 0;
}