Cod sursa(job #390281)

Utilizator ErgoVicol Sergiu Constantin Ergo Data 3 februarie 2010 13:39:03
Problema Barbar Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.19 kb
#include <fstream>
#include <queue>

#define mp make_pair
#define RMAX 1010

using namespace std;

char M[RMAX][RMAX];
int distDr[RMAX][RMAX], Dist[RMAX][RMAX];
int R, C, xSt, ySt, xFi, yFi, dx[]={1, 0, -1, 0, 1, 1, -1, -1}, dy[]={0, 1, 0, -1, 1, -1, 1, -1}, dMax;


priority_queue< pair<int, int> > Que;
queue<int> Q;

void Citeste(void)
{
	ifstream fin("barbar.in");
	
	int i, j;
	
	fin >>R >>C;
	fin.get();
	for (i = 1; i <= R; i++)
	{
		for (j = 1; j <= C; j++)
		{
			fin.get(M[i][j]);
			
			distDr[i][j] = -1;
			Dist[i][j] = -1;
			
			if (M[i][j] == 'D')
			{
				distDr[i][j] = 0;
				Q.push(i*1000+j);
				M[i][j] = '.';
			}
			if (M[i][j] == 'I')
				xSt = i, ySt = j, M[i][j] = '.';
			if (M[i][j] == 'O')
				xFi = i, yFi = j, M[i][j] = '.';
		}
		fin.get();
	}
	
	fin.close();
}

void calculeazaDistanteDragoni(void)
{
	int x, y, i, xp, yp;
	
	for (i = 0; i <= R + 1; i++)
		distDr[i][0] = distDr[i][C+1] = -2;
	for (i = 0; i <= C + 1; i++)
		distDr[0][i] = distDr[R+1][i] = -2;
	
	while(!Q.empty())
	{
		x = Q.front() / 1000;
		y = Q.front() % 1000;
		Q.pop();
		
		for (i = 0; i < 4; i++)
		{
			xp = x + dx[i];
			yp = y + dy[i];
			
			if(distDr[xp][yp] == -1)
			{
				distDr[xp][yp] = distDr[x][y] + 1;
				Q.push(xp*1000 + yp);
			}
		}
	}
}

inline int minim(int x, int y)
{
	if (x < y) return x;
	else return y;
}

void calcDistMaximaDragon()
{
	Que.push( mp(distDr[xSt][ySt], xSt*1000+ySt) );
	
	dMax= distDr[xSt][ySt];
	Dist[xSt][ySt] = distDr[xSt][ySt];
	
	int i, x, y, xp, yp;
	
	while(!Que.empty())
	{		
		x = (Que.top()).second / 1000;
		y = (Que.top()).second % 1000;
		Que.pop();
		
		for (i = 0; i < 4; i++)
		{
			xp = x + dx[i], yp = y + dy[i];
			
			if ( M[xp][yp] == '.' && Dist[xp][yp] == -1)
			{
				Dist[xp][yp] = minim(distDr[xp][yp], Dist[x][y]);
				
				Que.push(mp (distDr[xp][yp], xp*1000+yp));
			}
		}
	}
}

void Rezolva(void)
{
	calculeazaDistanteDragoni();
	
	calcDistMaximaDragon();
}

void Afiseaza(void)
{
	ofstream fout("barbar.out");
	
	fout <<Dist[xFi][yFi];
	
	fout.close();
}

int main()
{
	Citeste();
	
	Rezolva();
	
	Afiseaza();
	return 0;
}