Cod sursa(job #2032425)

Utilizator vancea.catalincatalin vancea.catalin Data 4 octombrie 2017 22:31:28
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.41 kb
//http://www.infoarena.ro/problema/barbar
#include<iostream>
#include<fstream>
#include<queue>
#define DX 1010
using namespace std;
fstream fin("barbar.in",ios::in),fout("barbar.out",ios::out);
int di[]={-1,0,1,0},dj[]={0,1,0,-1};// vectori de directii
int R,C,Ii,Ij,Oi,Oj; //indici
int dist[DX][DX]; //distanta de la dragoni pana la (i,j)
queue<int> qi,qj; //cozi pt bfs
short ok[DX][DX]; //numarul testului in cautarea binara
char x[DX][DX];   //matricea citita

bool vfi(int i) //verificare incadrare i
{
    return (0<=i && i<R);
}
bool vfj(int j) //verificare incadrare j
{
    return (0<=j && j<C);
}
void citire()
{
    int i,j;
    fin>>R>>C;
    for(i=0;i<R;i++) fin>>x[i];
    for(i=0;i<R;i++){
        for(j=0;j<C;j++){
            if(x[i][j]=='I'){
                Ii=i;Ij=j;
            }
            if(x[i][j]=='O'){
                Oi=i;Oj=j;
            }
            if(x[i][j]=='D')
            {
                qi.push(i);
                qj.push(j);
                dist[i][j]=1;
            }
            if(x[i][j]=='*')
                dist[i][j]=-DX;
        }
    }
}
void bfs()
{
    int i,j,k,a,b,c;
    while(qi.empty()==0)
    {
        i=qi.front();j=qj.front();
        qi.pop();qj.pop();
        c=dist[i][j]+1;
        for(k=0;k<4;k++)
        {
            a=i+di[k]; b=j+dj[k];
            if(vfi(a) && vfj(b) && dist[a][b]>=0)
            {
                if((dist[a][b]>c) || (dist[a][b]==0))
                {
                    dist[a][b]=c;
                    qi.push(a); qj.push(b);
                }
            }
        }
    }
}
int verificare(int mini,int ind)
{
    int i,j,k,a,b,c;
    qi.push(Ii);qj.push(Ij);
    while(qi.empty()==0)
    {
        i=qi.front(); j=qj.front();
        qi.pop();qj.pop();
        for(k=0;k<4;k++)
        {
            a=i+di[k]; b=j+dj[k];
            if(vfi(a) && vfj(b) && dist[a][b]>=mini && ok[a][b]!=ind)
            {
                ok[a][b]=ind;
                qi.push(a); qj.push(b);
            }
        }
    }
    if(ok[Oi][Oj]==ind) return 1;
    return 0;
}
int cautare_binara(int a,int b)
{
    int m,nr=0;
    while(a<b)
    {
        nr++;
        m=(a+b)/2+1;
        if(verificare(m,nr)==1)
            a=m;
        else
            b=m-1;
    }
    return a;
}
int main()
{
    int r;
    citire();
    bfs();
    r=cautare_binara(1,min(dist[Ii][Ij],dist[Oi][Oj]))-1;

    if(r==0)
        fout<<"-1\n";
    else
        fout<<r<<"\n";

    return 0;
}