Cod sursa(job #353630)

Utilizator andrei.sfrentSfrent Andrei andrei.sfrent Data 5 octombrie 2009 19:03:52
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.54 kb
#include <cstdio>
#include <queue>

using namespace std;

#define MAXN 1000

#define INCHIS -1
#define NEVIZITAT 10000

struct punct {int l, c; };

queue<punct> coada;
int h[MAXN + 2][MAXN + 2];
int n, m, x;
punct barbar, poarta;
char d[MAXN + 2][MAXN + 2];

int dl[4] = {1, -1, 0, 0};
int dc[4] = {0, 0, -1, 1};

void citeste()
{
	FILE* fi = fopen("barbar.in", "r");
	fscanf(fi, "%d%d\n", &n, &m);
	int i, j;
	punct aux;
	char s[MAXN + 2];
	for(i = 1; i <= n; ++i)
	{
		fscanf(fi, "%s\n", s + 1);
		for(j = 1; j <= m; ++j)
		{
			if(s[j] == '.') h[i][j] = NEVIZITAT;
			else if(s[j] == 'D')
			{
				h[i][j] = 0; //dragon
				aux.l = i;
				aux.c = j;
				coada.push(aux);
			}
			else if(s[j] == '*') h[i][j] = INCHIS;
			else if(s[j] == 'I')
			{
				h[i][j] = NEVIZITAT;
				barbar.l = i;
				barbar.c = j;
			}
			else
			{
				h[i][j] = NEVIZITAT;
				poarta.l = i;
				poarta.c = j;
			}
		}
	}
	fclose(fi);	
}

void bordeazaHarta()
{
	int i;
	for(i = 0; i <= n + 1; ++i) h[i][0] = h[i][m + 1] = INCHIS;
	for(i = 0; i <= m + 1; ++i) h[0][i] = h[n + 1][i] = INCHIS;
}

void lee()
{
	punct e, aux;
	int i, nl, nc;
	while(!coada.empty())
	{
		e = coada.front();
		coada.pop();
		
		for(i = 0; i < 4; ++i)
		{
			nl = e.l + dl[i];
			nc = e.c + dc[i];
			if(h[nl][nc] == NEVIZITAT)
			{
				h[nl][nc] = h[e.l][e.c] + 1;
				aux.l = nl;
				aux.c = nc;
				coada.push(aux);
			}
		}
	}
}

int incearcaDrum(int distMax)
{
	//incerc sa gasesc un drum pe care sa ma tin la distanta maxima de dragoni
	int i;
	
	//initializez d cu 0
	for(i = 1; i <= n; ++i)	memset(d[i] + 1, 0, m);
	
	//fac un fill
	punct e, aux;
	int nl, nc;
	coada.push(barbar);
	d[barbar.l][barbar.c] = 1;
	while(!coada.empty())
	{
		e = coada.front();
		coada.pop();
		for(i = 0; i < 4; ++i)
		{
			nl = e.l + dl[i];
			nc = e.c + dc[i];
			if(h[nl][nc] >= distMax && d[nl][nc] == 0)
			{
				d[nl][nc] = 1;
				aux.l = nl;
				aux.c = nc;
				coada.push(aux);
			}
		}
	}
	return d[poarta.l][poarta.c];
}

void scrie()
{
	FILE* fo = fopen("barbar.out", "w");
	fprintf(fo, "%d\n", x);
	fclose(fo);
}

void cautaBinar()
{
	int li = 1;
	int ls = h[barbar.l][barbar.c];
	int mij;
	
	while(ls - li > 1)
	{
		mij = (li + ls) / 2;
		if(incearcaDrum(mij))
			li = mij;
		else 
			ls = mij - 1;
	}
	if(incearcaDrum(ls))
		x = ls;
	else if(incearcaDrum(li))
		x = li;
	else
		x = -1;
}

int main()
{
	citeste();
	bordeazaHarta();
	lee();
	cautaBinar();
	scrie();
	return 0;
}