Cod sursa(job #1966527)

Utilizator tziplea_stefanTiplea Stefan tziplea_stefan Data 15 aprilie 2017 12:40:39
Problema Barbar Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 3 kb
#include <fstream>
#include <vector>
#include <queue>
#define VAL 1005

using namespace std;

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

struct pozitie
{
    int l, c;
};

pozitie poz, poz2;
pozitie start, finish;

const int dl[4]={-1, 0, 1, 0};
const int dc[4]={0, -1, 0, 1};

int N, M, i, j;
int dp[VAL][VAL];
char c[VAL][VAL];
bool ok[VAL][VAL];
vector <pozitie> drag;
vector <pozitie> :: iterator it;
queue <pozitie> Q;

void Complete(pozitie dragon, int dist, bool val)
{
    int lin, col, i;
    lin=dragon.l;
    col=dragon.c;
    for (i=col; i>=col-dist; i--)
    {
        if (c[lin][i]=='*' || i==0)
          break;
        ok[lin][i]=val;
    }
    for (i=col; i<=col+dist; i++)
    {
        if (c[lin][i]=='*' || i==M+1)
          break;
        ok[lin][i]=val;
    }
    for (i=lin; i>=lin-dist; i--)
    {
        if (c[i][col]=='*' || i==0)
          break;
        ok[i][col]=val;
    }
    for (i=lin; i<=lin+dist; i++)
    {
        if (c[i][col]=='*' || i==N+1)
          break;
        ok[i][col]=val;
    }
}

void Lee()
{
    if (ok[start.l][start.c]==false)
    {
        int i;
        dp[start.l][start.c]=1;
        Q.push(start);
        while (Q.empty()==false)
        {
            poz=Q.front();
            Q.pop();
            for (i=0; i<=3; i++)
            {
                poz2.l=poz.l+dl[i];
                poz2.c=poz.c+dc[i];
                if (ok[poz2.l][poz2.c]==false && c[poz2.l][poz2.c]!='*')
                {
                    if (dp[poz2.l][poz2.c]==0 || dp[poz2.l][poz2.c]>dp[poz.l][poz.c]+1)
                    {
                        dp[poz2.l][poz2.c]=dp[poz.l][poz.c]+1;
                        Q.push(poz2);
                    }
                }
            }
        }
    }
}

bool Verify(int dist)
{
    int i, j;
    for (i=1; i<=N; i++)
      for (j=1; j<=M; j++)
        dp[i][j]=0;
    for (it=drag.begin(); it!=drag.end(); it++)
      Complete(*it, dist, 1);
    Lee();
    for (it=drag.begin(); it!=drag.end(); it++)
      Complete(*it, dist, 0);
    return dp[finish.l][finish.c]>0;
}

int Binary_Search()
{
    int be=0, en=max(N, M);
    int mid, ans=-1;
    while (be<=en)
    {
        mid=(be+en) / 2;
        if (Verify(mid-1)==true)
        {
            ans=mid;
            be=mid+1;
        }
        else
          en=mid-1;
    }
    return ans;
}

int main()
{
    fin >> N >> M;
    for (i=0; i<=N+1; i++)
      c[i][0]=c[i][M+1]='*';
    for (i=0; i<=M+1; i++)
      c[0][i]=c[N+1][i]='*';
    for (i=1; i<=N; i++)
    {
        for (j=1; j<=M; j++)
        {
            fin >> c[i][j];
            if (c[i][j]=='D')
            {
                poz.l=i;
                poz.c=j;
                drag.push_back(poz);
            }
            if (c[i][j]=='I')
            {
                start.l=i;
                start.c=j;
            }
            if (c[i][j]=='O')
            {
                finish.l=i;
                finish.c=j;
            }
        }
    }
    fout << Binary_Search() << '\n';
    fin.close();
    fout.close();
    return 0;
}