Cod sursa(job #917760)

Utilizator fhandreiAndrei Hareza fhandrei Data 18 martie 2013 12:23:14
Problema Barbar Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.16 kb
// Include
#include <fstream>
#include <queue>
using namespace std;

// Definitii
#define mp make_pair

#define type_coord pair<int, int>
#define x first
#define y second

// Constante
const int sz = 1001;
const int oo = (1<<30)-1;

// Functii
void bs(int left, int right);
bool lee(int maxDist);

// Variabile
ifstream in("barbar.in");
ofstream out("barbar.out");

int lines, columns;
type_coord start, finish;

bool wallMatrix[sz][sz];
int dragonMatrix[sz][sz];
bool visited[sz][sz];
int answer;

queue<type_coord> q;

// Main
int main()
{
	in >> lines >> columns;
	
	for(int i=1 ; i<=lines ; ++i)
		for(int j=1 ; j<=columns ; ++j)
			dragonMatrix[i][j] = oo;
	
	
	char readChar;
	queue<type_coord> q;
	for(int i=1 ; i<=lines ; ++i)
	{
		for(int j=1 ; j<=columns ; ++j)
		{
			in >> readChar;
			if(readChar == 'I')
				start = mp(i, j);
			if(readChar == '0')
				finish = mp(i, j);
			if(readChar == 'D')
			{
				q.push(mp(i, j));
				dragonMatrix[i][j] = 1;
			}
			if(readChar == '*')
				wallMatrix[i][j] = true;
		}
	}
	
	while(!q.empty())
	{
		type_coord current = q.front();
		q.pop();
		if(dragonMatrix[current.x][current.y] < dragonMatrix[current.x-1][current.y])
		{
			dragonMatrix[current.x-1][current.y] = dragonMatrix[current.x][current.y] + 1;
			q.push(mp(current.x-1, current.y));
		}
		if(dragonMatrix[current.x][current.y] < dragonMatrix[current.x+1][current.y])
		{
			dragonMatrix[current.x+1][current.y] = dragonMatrix[current.x][current.y] + 1;
			q.push(mp(current.x+1, current.y));
		}
		if(dragonMatrix[current.x][current.y] < dragonMatrix[current.x][current.y-1])
		{
			dragonMatrix[current.x][current.y-1] = dragonMatrix[current.x][current.y] + 1;
			q.push(mp(current.x, current.y-1));
		}
		if(dragonMatrix[current.x][current.y] < dragonMatrix[current.x][current.y+1])
		{
			dragonMatrix[current.x][current.y+1] = dragonMatrix[current.x][current.y] + 1;
			q.push(mp(current.x, current.y+1));
		}
	}
	
	bs(1, 4500);
	out << answer-1 << '\n';
	
	in.close();
	out.close();
	return 0;
}

void bs(int left, int right)
{
	while(left <= right)
	{
		int mid = (left + right) / 2;
		
		if(lee(mid))
		{
			answer = mid;
			right = mid-1;
		}
		else
			left = mid+1;
	}
}

bool lee(int maxDist)
{
	queue<type_coord> q;
	q.push(start);
	visited[start.x][start.y] = true;
	
	memcpy(visited, wallMatrix, sizeof(visited));
	
	while(!q.empty() && !visited[finish.x][finish.y])
	{
		type_coord current = q.front();
		q.pop();
		
		if(maxDist < dragonMatrix[current.x][current.y]-1)
			continue;
		
		if(!visited[current.x-1][current.y])
		{
			visited[current.x-1][current.y] = true;
			q.push(mp(current.x-1, current.y));
		}
		if(!visited[current.x+1][current.y])
		{
			visited[current.x+1][current.y] = true;
			q.push(mp(current.x+1, current.y));
		}
		if(!visited[current.x][current.y-1])
		{
			visited[current.x][current.y-1] = true;
			q.push(mp(current.x, current.y-1));
		}
		if(!visited[current.x][current.y+1])
		{
			visited[current.x][current.y+1] = true;
			q.push(mp(current.x, current.y+1));
		}
	}
	
	return visited[finish.x][finish.y];
}