Cod sursa(job #44361)

Utilizator peanutzAndrei Homorodean peanutz Data 31 martie 2007 12:04:22
Problema Barbar Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.76 kb
#include <stdio.h>
#include <memory.h>
#include <string.h>

#define NMAX 1510

typedef struct coada
{
int x, y;
};

char a[NMAX][NMAX];
coada c[250000];
int n, m;
int min[NMAX][NMAX];
int inc, sf = -1;
int inx, iny, outx, outy;
int until[NMAX][NMAX];

void bordare()
{
	int i;

	for(i = 0; i <= n+1; ++i)
	{
		a[i][0] = a[i][m+1] = '*';
	}
	for(i = 0; i <= m+1; ++i)
	{
		a[0][i] = a[n+1][i] = '*';
	}
}

void read()
{
	int i, j;
	scanf("%d %d\n", &n, &m);

	bordare();

	for(i = 1; i <= n; ++i)
	{
		scanf("%s\n", a[i]+1);
		for(j = 1; j <= m; ++j)
		{
			if(a[i][j] == 'D')
			{
				c[++sf].x = i;
				c[sf].y = j;
				min[i][j] = 0;
			}
			else if(a[i][j] == 'I')
			{
				inx = i;
				iny = j;
				a[i][j] = '.';
			}
			else if(a[i][j] == 'O')
			{
				outx = i;
				outy = j;
				a[i][j] = '.';
			}
		}
	}
}
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
void lee_dragoni()
{

	int x, y;
	int i;
	int nextx, nexty;

	while(inc <= sf)
	{
		x = c[inc].x;
		y = c[inc++].y;

		for(i = 0; i < 4; ++i)
		{
			nextx = x + dx[i];
			nexty = y + dy[i];

			if((a[nextx][nexty] == '.') &&  (min[nextx][nexty] > min[x][y] + 1))
			{
				c[++sf].x = nextx;
				c[sf].y = nexty;

				min[nextx][nexty] = min[x][y] + 1;
			}
		}
	}
}

void print_min()
{
	int i, j;

	for(i = 0; i <= n+1; ++i)
	{
		for(j = 0; j <= m+1; ++j)
		{
			printf("%d ", min[i][j]);
		}
		printf("\n");
	}
}

void print_a()
{
	int i, j;

	printf("\n");
	for(i = 0; i <= n+1; ++i)
	{
		for(j = 0; j <= m+2; ++j)
		{
			printf("%c ", a[i][j]);
		}
		printf("\n");

	}
}

int lee_in_out(int m)
{
	int x, y;
	coada c[250000];
	int inc, sf;
	int nextx, nexty;
	int j;

	//memset(c, 0, sizeof(c));
	memset(until, 0, sizeof(until));

	c[0].x = inx;
	c[0].y = iny;

	inc = sf = 0;

	while(inc <= sf)
	{
		x = c[inc].x;
		y = c[inc++].y;

		for(j = 0; j < 4; ++j)
		{
			nextx = x + dx[j];
			nexty = y + dy[j];

			if(a[nextx][nexty] != '*'  &&  min[nextx][nexty] >= m  && !until[nextx][nexty])
			{
				c[++sf].x = nextx;
				c[sf].y = nexty;

				++until[nextx][nexty];
			}

			if(nextx == outx && nexty == outy)
			{
				return 1;
			}
		}
	}
	return 0;
}
void binary_search()
{
	int st, dr;
	int mijloc;
	int keep = -1;
	st = 1;
	dr = (n + m) * 5;

	while(st <= dr)
	{
		m = (st + dr)/2;

		if(lee_in_out(m))
		{
			st = m+1;
			keep = m;
		}
		else
		{
			dr = m-1;
		}
	}

	printf("%d\n", keep);
}

int main()
{
	freopen("barbar.in", "r", stdin);
	freopen("barbar.out", "w", stdout);

	memset(min, 0x3f, sizeof(min));

	read();

	lee_dragoni();

	//print_min();
	//print_a();

	binary_search();

	fclose(stdin);
	fclose(stdout);

	return 0;
}