Cod sursa(job #1617516)

Utilizator qwertyuiTudor-Stefan Berbinschi qwertyui Data 27 februarie 2016 14:53:17
Problema Barbar Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.56 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <utility>
#include <algorithm>

using namespace std;

ifstream fin ("barbar.in");
ofstream fout ("barbar.out");

int dx[] = {0, 0, 1, -1};
int dy[] = {-1, 1, 0, 0};

queue < pair <int,int> > LeeQ, FillQ;
pair <int, int> start, finish;
int A[1050][1050];
bool used[1050][1050];
int N, M, MinDragonDist;

int Fill (int Val)
{

	for (int i = 0; i <= N+1; ++i)
		for (int j = 0; j <= M+1; ++j)
			used[i][j] = 0;

	FillQ.push(start);

    while(!FillQ.empty())
	{
        int X = FillQ.front().first;
        int Y = FillQ.front().second;

        FillQ.pop();

        for(int i = 0; i < 4; ++i)
		{
            int _X = X + dx[i];
            int _Y = Y + dy[i];

            if(!used[_X][_Y] && A[_X][Y] >= Val)
			{
                used[_X][_Y] = 1;
                FillQ.push(make_pair(_X,_Y));
			}

		}
	}

    return used[finish.first][finish.second];

}

void Lee()
{

    while(LeeQ.size())
	{

        int X = LeeQ.front().first;
        int Y = LeeQ.front().second;

        LeeQ.pop();

        for(int i = 0; i < 4; ++i)
		{

            int _X = X + dx[i];
            int _Y = Y + dy[i];

            if(!A[_X][_Y])
			{
                A[_X][_Y] = A[X][Y] + 1;
                LeeQ.push(make_pair(_X,_Y));
			}

            if(A[_X][_Y] > A[X][Y] + 1)
                A[_X][_Y] = A[X][Y] + 1;
		}
	}
}

int main()
{
    char S[1050];
    fin >>N >>M;

    fin.getline(S,1049);

    for (int i = 1; i <= N; ++i)
    {
		fin.getline(S+1, 1049);

		for (int j = 1; j <= M; ++j)
			switch(S[j])
			{
                case '.':
                	break;

                case '*':
                	A[i][j] = -1;
                	break;

                case 'D':
                	A[i][j] = 1;
					LeeQ.push(make_pair(i,j));
					break;

                case 'I':
                	start = make_pair(i,j);
                	break;

                case 'O':
                	finish = make_pair(i,j);
                	break;

			}
    }

    for (int i = 0; i <= N+1; ++i)
		A[i][0] = A[i][M+1] = -1;

	for (int i = 0; i <= M+1; ++i)
		A[0][i] = A[N+1][i] = -1;

	Lee();

    int right = min(A[start.first][start.second], A[finish.first][finish.second]);

    int k, left;
    for(k = 1; k < right; k <<= 1);

    for (left = 0; k ; k>>=1)
        if(k+left <= right && Fill(left+k))
            left += k;

    MinDragonDist = left + k - 1;

    fout <<MinDragonDist <<'\n';

    return 0;
}