Cod sursa(job #328408)

Utilizator cosmin79Carabet Cosmin Andrei cosmin79 Data 1 iulie 2009 22:16:36
Problema Barbar Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.47 kb
#include <stdio.h>
#define N 1005
#define inf 5000000
int m,n,r,crd1,crd2,crd3,crd4,rez,sol[5],solutie;
int v[N][N],mat[N][N];
int dlin[]={0,0,-1,1};
int dcol[]={1,-1,0,0};
char marc[N][N];
struct coord
{
	int a,b;
};
coord dragon[N];
struct bfs
{
	int a,b,cost;
};
bfs coada[N*N];
int min[N][N],bani[N][N];
void read()
{
	char x;
	scanf("%d%d\n",&m,&n);
	int lin=1,col=0;
	while (scanf("%c",&x)!=EOF)
	{
		if (x=='\n')
		{
			lin++;
			col=0;
			continue;
		}
		if (x=='.')
		{
			v[lin][++col]=0;
			continue;
		}
		if (x=='I')
		{
			v[lin][++col]=0;
			crd1=lin;
			crd2=col;
			continue;
		}
		if (x=='O')
		{
			v[lin][++col]=0;
			crd3=lin;
			crd4=col;
			continue;
		}
		if (x=='D')
		{
			v[lin][++col]=0;
			dragon[++r].a=lin;
			dragon[r].b=col;
			continue;
		}
		if (x=='*')
		{
			v[lin][++col]=1;
			marc[lin][col]=1;
			continue;
		}
	}
}
void bordare()
{
	int i;
	for (i=0; i<=n+1; i++)
	{
		marc[0][i]=1;
		marc[m+1][i]=1;
	}
	for (i=0; i<=m+1; i++)
	{
		marc[i][0]=1;
		marc[i][n+1]=1;
	}
}
void bfs1()
{
	int i,j,ok=1,ant=0,act;
	bordare();
	for (i=1; i<=r; i++)
	{
		coada[i].a=dragon[i].a;
		coada[i].b=dragon[i].b;
		coada[i].cost=0;
		marc[coada[i].a][coada[i].b]=1;
	}
	while (ok)
	{
		ok=0;
		act=r;
		for (i=ant+1; i<=act; i++)
			for (j=0; j<4; j++)
			{
				if (v[coada[i].a+dlin[j]][coada[i].b+dcol[j]]==0 && marc[coada[i].a+dlin[j]][coada[i].b+dcol[j]]==0)
				{
					coada[++r].a=coada[i].a+dlin[j];
					coada[r].b=coada[i].b+dcol[j];
					coada[r].cost=coada[i].cost+1;
					marc[coada[r].a][coada[r].b]=1;
					mat[coada[r].a][coada[r].b]=r;
					ok=1;
				}
			}
		ant=act;
	}
}
void precalculation()
{
	int i,j;
	for (i=1; i<=m; i++)
		for (j=1; j<=n; j++)
		{
			if (v[i][j]==1)
			{
				mat[i][j]=-1;
				continue;
			}
			if (marc[i][j]==0)
			{
				mat[i][j]=-1;
				continue;
			}
			mat[i][j]=coada[mat[i][j]].cost;
		}
}
void bordare2()
{
	int i,j;
	for (i=0; i<=m+1; i++)
		for (j=0; j<=n+1; j++)
			marc[i][j]=0;
	for (i=1; i<=m; i++)
		for (j=1; j<=n; j++)
			if (v[i][j]==1)
				marc[i][j]=1;
	for (i=0; i<=n+1; i++)
	{
		marc[0][i]=1;
		marc[m+1][i]=1;
	}
	for (i=0; i<=m+1; i++)
	{
		marc[i][0]=1;
		marc[i][n+1]=1;
	}
}
int minim(int a,int b)
{
	if (a<b)
		return a;
	return b;
}
void walking()
{
	bordare2();
	r=0;
	int i,j,fin=1,ant=0,act;
	coada[++r].a=crd1;
	coada[r].b=crd2;
	bani[crd1][crd2]=0;
	min[crd1][crd2]=mat[crd1][crd2];
	marc[crd1][crd2]=2;
	while (fin)
	{
		fin=0;
		act=r;
		for (i=ant+1; i<=act; i++)
			for (j=0; j<4; j++)
			{
				if (marc[coada[i].a+dlin[j]][coada[i].b+dcol[j]]==2)
				{
					if (bani[coada[i].a][coada[i].b]+1==bani[coada[i].a+dlin[j]][coada[i].b+dcol[j]])
						if (min[coada[i].a][coada[i].b]<min[coada[i].a+dlin[j]][coada[i].b+dcol[j]])
							min[coada[i].a+dlin[j]][coada[i].b+dcol[j]]=min[coada[i].a][coada[i].b];
				}
				if (marc[coada[i].a+dlin[j]][coada[i].b+dcol[j]]==0)
				{
					coada[++r].a=coada[i].a+dlin[j];
					coada[r].b=coada[i].b+dcol[j];
					bani[coada[r].a][coada[r].b]=bani[coada[i].a][coada[i].b]+1;
					min[coada[r].a][coada[r].b]=minim(min[coada[i].a][coada[i].b],mat[coada[r].a][coada[r].b]);
					fin=1;
					marc[coada[i].a+dlin[j]][coada[i].b+dcol[j]]=2;
				}
			}
		if (marc[crd3][crd4]==2)
			break;
		ant=act;
	}
	if (marc[crd3][crd4]!=2)
		solutie=0;
	else
		rez=min[crd3][crd4];
}
int main()
{
	freopen("barbar.in","r",stdin);
	freopen("barbar.out","w",stdout);
	read();
	bfs1();
	precalculation();
	walking();
	if (solutie==0)
		printf("-1\n");
	else
		printf("%d\n",rez);
	return 0;
}