Cod sursa(job #1816244)

Utilizator teo.cons98Constantin Teodor-Claudiu teo.cons98 Data 26 noiembrie 2016 11:52:36
Problema Barbar Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.46 kb
#include<iostream>
#include<fstream>
#include<cstdlib>
using namespace std;

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

char A[1001][1001];
int n, m, pozix, poziy, pozBuna;
int B[1001][1001];
int distDrag[1001][1001], px[1000001], py[1000001];

void citire()
{
    fin>>n>>m;
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= m; ++j)
        {
            fin>>A[i][j];
            if(A[i][j] == 'I')
            {
                pozix = i;
                poziy = j;
            }
        }
}

void golB()
{
    for(int i = 1; i <= n; ++i)
    {
        for(int j = 1; j <= m; ++j)
        {
            B[i][j] = 0;
        }
    }
}

int verificare(int distMin)
{
    golB();
    int  p = 1, u = 1, x, y;
    px[1] = pozix;
    py[1] = poziy;
    B[px[1]][py[1]] = 1;
    while(p <= u)
    {
        x = px[p];
        y = py[p];
        if(A[x - 1][y] == '.' and distDrag[x - 1][y] >= distMin and B[x - 1][y] == 0 and x - 1 >= 1)
        {
            ++u;
            px[u] = x - 1;
            py[u] = y;
            B[x - 1][y] = 1;
        }
        if(A[x - 1][y] == 'O' and distDrag[x - 1][y] >= distMin and x - 1 >= 1)
        {
            return 1;
            p = u + 10;
            break;
        }
        if(A[x + 1][y] == '.' and distDrag[x + 1][y] >= distMin and B[x + 1][y] == 0 and x + 1 <= n)
        {
            ++u;
            px[u] = x + 1;
            py[u] = y;
            B[x + 1][y] = 1;
        }
        if(A[x + 1][y] == 'O' and distDrag[x + 1][y] >= distMin and x + 1 <= n)
        {
            return 1;
            p = u + 10;
            break;
        }
        if(A[x][y - 1] == '.' and distDrag[x][y - 1] >= distMin and B[x][y - 1] == 0 and y - 1 >= 1)
        {
            ++u;
            px[u] = x;
            py[u] = y - 1;
            B[x][y-1]= 1;
        }
        if(A[x][y - 1] == 'O' and distDrag[x][y - 1] >= distMin and y - 1 >= 1)
        {
            return 1;
            p = u + 10;
            break;
        }
        if(A[x][y + 1] == '.' and distDrag[x][y + 1] >= distMin and B[x][y + 1] == 0 and y + 1 <= m)
        {
            ++u;
            px[u] = x;
            py[u] = y + 1;
            B[x][y+1] = 1;
        }
        if(A[x][y + 1] == 'O' and distDrag[x][y + 1] >= distMin and y + 1 <= m)
        {
            return 1;
            p = u + 10;
            break;
        }
        ++p;
    }
    return 0;
}

void cautBin(int prim, int ult)
{
    if(prim <= ult)
    {
        int mid = (prim + ult) / 2;
        if(distDrag[pozix][poziy] >= mid)
        {
            if(verificare(mid))
            {
                pozBuna = mid;
                cautBin(mid + 1, ult);
            }
            else
            {
                cautBin(prim, mid - 1);
            }
        }
        else
        {
            cautBin(prim, mid - 1);
        }
    }

}

void calcDistDrag()
{
    for(int i = 1; i <= n; ++i)
    {
        for(int j = 1; j <= m; ++j)
        {
            if(A[i][j] == 'D')
            {
                for(int i1 = 1; i - i1 >= 1; ++i1)
                {
                    if(A[i - i1][j] == 'D') break;
                    else if(distDrag[i - i1][j] == 0 or distDrag[i - i1][j] > i1)
                        distDrag[i - i1][j] = i1;
                }
                for(int i1 = 1; i + i1 <= n; ++i1)
                {
                    if(A[i + i1][j] == 'D') break;
                    else distDrag[i + i1][j] = i1;
                }
                for(int j1 = 1; j - j1 >= 1; ++j1)
                {
                    if(A[i][j - j1] == 'D') break;
                    else if(distDrag[i][j - j1] == 0 or distDrag[i][j - j1] > j1)
                        distDrag[i][j - j1] = j1;
                }
                for(int j1 = 1; j + j1 <= m; ++j1)
                {
                    if(A[i][j + j1] == 'D') break;
                    else if(distDrag[i][j + j1] == 0 or distDrag[i][j + j1] > j1)
                        distDrag[i][j + j1] = j1;
                }
            }
        }
    }
    for(int i = 1; i <= n; ++i)
    {
        for(int j = 1; j <= m; ++j)
        {
            if(distDrag[i][j] == 0)
            {
                distDrag[i][j] = 1000001;
            }
        }
    }
}

int main()
{
    citire();
    calcDistDrag();
    cautBin(1,1000);
    if(pozBuna == 0) fout<<"-1";
    else fout<<pozBuna;
}