Cod sursa(job #558638)

Utilizator iconiKMircea Chirea iconiK Data 17 martie 2011 13:12:04
Problema Barbar Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.25 kb
#include <algorithm>
#include <climits>
#include <fstream>
#include <queue>
#include <string>
#include <vector>
#include <utility>
using namespace std;

typedef pair<int,int> celula;
typedef vector<vector<int> > matrix;

enum tip
{
	zid = -1,
	dragon = 0,
	liber = INT_MAX
};

int R, C, Xi, Yi, Xo, Yo;
int vx[] = {-1, 0, 1, 0}, vy[] = {0, 1, 0, -1};
int viz[1001][1001];
matrix a;

int main()
{
	ifstream in("barbar.in");
	in >> R >> C;
	in.get();

	a.resize(R + 2);
	for (matrix::iterator i = a.begin(); i != a.end(); i++)
		i->resize(C + 2, zid);

	queue<celula> q;

	for (int i = 1; i <= R; i++)
	{
		for (int j = 1; j <= C; j++)
		{
			char c;
			in >> c;

			switch (c)
			{
			case '*':
				a[i][j] = zid;
				break;
			case 'D':
				a[i][j] = dragon;
				q.push(make_pair(i, j));
				viz[i][j] = true;
				break;
			case '.':
				a[i][j] = liber;
				break;
			case 'I':
				a[i][j] = liber;
				Xi = i; Yi = j;
				break;
			case 'O':
				a[i][j] = liber;
				Xo = i; Yo = j;
				break;
			}
		}

		in.get();
	}

	for (; !q.empty(); q.pop())
	{
		celula cell = q.front();

		for (int i = 0; i <= 3; i++)
		{
			int l = cell.first + vx[i];
			int c = cell.second + vy[i];

			if (a[l][c] != zid && !viz[l][c])
			{
				q.push(make_pair(l, c));
				viz[l][c] = true;
				a[l][c] = a[cell.first][cell.second] + 1;
			}
		}
	}

	int p = 0;
	int u = R + C;
	int t = -1;
	int v = 0;

	while (p <= u)
	{
		int m = (p + u) / 2;
		bool ok = false;

		if (a[Xi][Yi] >= m)
		{
			queue<celula> q2;
			memset(viz, 0, 1001 * 1001);
			
			for (q2.push(make_pair(Xi, Yi)), viz[Xi][Yi] = true; !q2.empty() && !ok; q2.pop())
			{
				celula cell = q2.front();

				for (int i = 0; i <= 3; i++)
				{
					int l = cell.first + vx[i];
					int c = cell.second + vy[i];

					if (a[l][c] != zid && a[l][c] >= m && !viz[l][c] && a[l][c] != INT_MAX)
					{
						q2.push(make_pair(l, c));
						viz[l][c] = true;

						if (l == Xo && c == Yo)
						{
							ok = true;
							break;
						}
					}
				}
			}
		}
		else
		{
			ok = false;
		}

		if (ok)
		{
			t = m;
			v = 1;
			p = m + 1;
		}
		else
		{
			u = m - 1;
		}
	}

	ofstream out("barbar.out");
	out << t;
}