Cod sursa(job #1236896)

Utilizator radu_cebotariRadu Cebotari radu_cebotari Data 2 octombrie 2014 19:11:26
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.75 kb
#include<fstream>
#include<queue>
#include<iostream>
#include<cstring>
using namespace std;
ifstream in("barbar.in");
ofstream out("barbar.out");
const int DMAX = 2000;

char v[DMAX][DMAX];
int n,m,viz[DMAX][DMAX],sol[DMAX][DMAX],MAX;
int d1[] = {1,0,-1,0};
int d2[] = {0,1,0,-1};
struct punct{
    int x,y;
};
punct start,finish;
queue<punct> coada;

void citire()
{
    punct now;
    in>>n>>m;
    for(int i = 1 ; i <= n ; i++)
        for(int j = 1 ; j <= m ; j++){

            in>>v[i][j];
            if(v[i][j] == 'I'){
                start.x = i;
                start.y = j;
                v[i][j] = '.';
            }
            else if(v[i][j] == 'O'){
                finish.x = i;
                finish.y = j;
                v[i][j] = '.';
            }
            else if(v[i][j] == 'D'){
                now.x = i;
                now.y = j;
                coada.push(now);
                viz[now.x][now.y] = 1;
                v[i][j] = '.';
            }
        }
    for(int i = 0 ; i <= n+1 ; i++)
        v[i][0] = v[i][m+1] = '*';
    for(int i = 0 ; i <= m+1 ; i++)
        v[0][i] = v[n+1][i] = '*';
    in.close();
}

void lee()
{

    punct now,k;
    int i;
    while(!coada.empty())
    {
        k = coada.front();
        for(i = 0 ; i < 4 ; i++){
            now.x = k.x+d1[i];
            now.y = k.y+d2[i];
            if(!viz[now.x][now.y] && v[now.x][now.y] != '*'){
                sol[now.x][now.y] = sol[k.x][k.y] + 1;
                MAX = max(MAX,sol[now.x][now.y]);
                coada.push(now);
                viz[now.x][now.y] = 1;
            }
        }
        coada.pop();
    }
}

void elib()
{

    while(!coada.empty())
        coada.pop();
}

bool ok(int distanta)
{

    memset(viz,0,sizeof(viz));
    viz[start.x][start.y] = 1;
    coada.push(start);
    punct k,now;
    int i;
    while(!coada.empty())
    {
        k = coada.front();
        for(i = 0 ; i < 4 ; i++)
        {
            now.x = k.x+d1[i];
            now.y = k.y+d2[i];
            if(!viz[now.x][now.y] && sol[now.x][now.y] >= distanta && v[now.x][now.y] == '.'){
                if(now.x == finish.x && now.y == finish.y){
                    elib();
                    return true;
                }
                viz[now.x][now.y] = 1;
                coada.push(now);
            }
        }
        coada.pop();
    }
    return false;
}

int solve()
{
    int st = 1,dr = MAX,s = -1,mij;
    while(st <= dr){
        mij = (st+dr)>>1;
        if(ok(mij))
            s = mij,st = mij+1;
        else
            dr = mij - 1;
    }
    return s;
}

int main()
{

    citire();
    lee();
    out<<solve();
    out.close();
    return 0;
}