Cod sursa(job #218670)

Utilizator ilincaSorescu Ilinca ilinca Data 2 noiembrie 2008 22:26:23
Problema Barbar Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.32 kb
#include <stdio.h>

#define maxn 1005
#define inf maxn*maxn
#define pr(x) fprintf(stderr,#x" = %d\n",x)

struct marmota 
{
	int l, c;
};

int r, c, p=1, maxim, u, m [maxn] [maxn], v [maxn] [maxn];
char w [maxn] [maxn];
marmota pi, po, q [maxn*maxn*5];

void scan ()
{
	int i, j;
	scanf ("%d%d\n", &r, &c);
	for (i=1; i<=r; ++i)
		for (j=1; j<=c; ++j)
		{
			scanf("%c ", &w [i] [j]);
			if (w [i] [j] == '.')
				m [i] [j]=inf;
			else
				if (w [i] [j] == '*')
					m [i] [j]=-1;
				else
					if (w [i] [j] == 'D')
					{	
						m [i] [j]=0;
						q [++u].l=i;
						q [u].c=j;
					}
					else
						if (w [i] [j] == 'I')
						{
							m [i] [j]=inf;
							pi.l=i;
							pi.c=j;
						}
						else
							if (w [i] [j] == 'O')
							{	
								m [i] [j]=inf;
								po.l=i;
								po.c=j;
							}
		}
}

void bordare ()
{
	int i, j, r1=r+1, c1=c+1;
	for (i=0; i<=r; ++i)
		m [i] [0]=m [i] [r1]=-1;
	for (j=0; j<=c; ++j)
		m [0] [j]=m [c1] [j]=-1;
}

void lee ()
{
	int i, la, ca, dl []={0, 0, 0, 1, -1}, dc []={0, -1, 1, 0, 0};
	while (p <= u)
	{
		for (i=1; i<=4; ++i)
		{
			la=q [p].l+dl [i];
			ca=q [p].c+dc [i];
			if (m [la] [ca] > m [q [p].l] [q [p].c]+1)
			{
				m [la] [ca]=m [q [p].l] [q [p].c]+1;
				if (m [la] [ca] > maxim)
					maxim=m [la] [ca];
				q [++u].l=la;
				q [u].c=ca;
			}
		}
		++p;
	}
}

void init ()
{
	int i, j;
	for (i=1; i<=r; ++i)
		for (j=1; j<=c; ++j)
			v [i] [j]=0;
}

int lee2 (int k)
{
	int i, la, ca, dl []={0, 0, 0, 1, -1}, dc []={0, -1, 1, 0, 0};
	p=u=1;
	q [p].l=pi.l;
	q [p].c=pi.c;
	init ();
	v [pi.l] [pi.c]=1;
	while (p <= u)
	{
		for (i=1; i<=4; ++i)
		{
			la=q [p].l+dl [i];
			ca=q [p].c+dc [i];
			if (m [la] [ca] >= k && !v [la] [ca])
			{
				q [++u].l=la;
				q [u].c=ca;
				v [la] [ca]=1;
				if (la == po.l && ca == po.c)
					return 1;
			}
		}
		++p;
	}
	return 0;
}

/*int cautbin (int st, int dr)
{
	int mij, k, b=-1;
	while (st < dr)
	{
		mij=(st+dr)/2;
		k=lee2 (mij);
		if (k)
		{
			st=mij+1;
			b=mij;
		}
		else
			dr=mij;
	}
	return (b<m [pi.l] [pi.c])? b:m [pi.l] [pi.c];
}*/

int cautbin ()
{
	int i, step;
	for (step=1; step<=maxim; step<<=1);
	for (i=0; step; step>>=1)
		if (lee2 (i+step-1))
			i+=step;
	return i-1;

}

int main ()
{
	freopen ("barbar.in", "r", stdin);
	freopen ("barbar.out", "w", stdout);
	scan ();
	bordare ();
	lee ();
	printf ("%d\n", cautbin ());
	return 0;
}