Cod sursa(job #2093969)

Utilizator iDanyelArvat Ovidiu Daniel iDanyel Data 24 decembrie 2017 18:39:35
Problema Barbar Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.41 kb
#include <iostream>
#include <fstream>
#include <queue>
using namespace std;

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

queue < pair < int, int > > Q;

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

struct coordonate
{
    int x, y;
}dragon[10010];

int n, m, k, v[1010][1010], S[1010][1010];
int x1, y1, x2, y2;

void reset()
{
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            S[i][j]=v[i][j];
}

void update(int P)
{
    for(int t=1;t<=k;t++)
    {
        //Directia Nord

        for(int i=dragon[t].x;i>=dragon[t].x-P+1&&i>=1;i--)
            S[i][dragon[t].y]=-1;

        //Directia Sud

        for(int i=dragon[t].x;i<=dragon[t].x+P-1&&i<=n;i++)
            S[i][dragon[t].y]=-1;

        //Directia Vest

        for(int j=dragon[t].y;j>=dragon[t].y-P+1&&j>=1;j--)
            S[dragon[t].x][j]=-1;

        //Directia Est

        for(int j=dragon[t].y;j<=dragon[t].y+P-1&&j<=m;j++)
            S[dragon[t].x][j]=-1;
    }
}

bool inauntru(int x, int y)
{
    if(x<1||y<1||x>n||y>m)
        return false;

    return true;
}

bool passed(int x, int y, int P)
{
    reset();
    update(P);

    S[x][y]=1;
    Q.push(make_pair(x,y));

    while(!Q.empty())
    {
        int ii=Q.front().first, jj=Q.front().second;
        Q.pop();

        for(int dir=0;dir<4;dir++)
            if(inauntru(ii+dx[dir],jj+dy[dir])&&!S[ii+dx[dir]][jj+dy[dir]])
            {
                S[ii+dx[dir]][jj+dy[dir]]=S[ii][jj]+1;
                Q.push(make_pair(ii+dx[dir],jj+dy[dir]));
            }
    }

    if(S[x2][y2]>0)
        return true;

    return false;
}

int binary()
{
    int li=1, lf=n, MAX=0;

    while(li<=lf)
    {
        int mid=(li+lf)/2;

        if(passed(x1,y1,mid))
            MAX=mid, li=mid+1;
        else
            lf=mid-1;
    }

    return MAX;
}

int main()
{
    fin >> n >> m;

    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            char c;
            fin >> c;

            if(c=='D')
                v[i][j]=-2, dragon[++k].x=i, dragon[k].y=j;

            else if(c=='*')
                v[i][j]=-1;

            else if(c=='I')
                x1=i, y1=j;

            else if(c=='O')
                x2=i, y2=j;
        }

    int value=binary();

    if(!value)
        fout << "-1";
    else
        fout << value;

    return 0;
}