Cod sursa(job #1303584)

Utilizator wGEORGEWGeorge Cioti wGEORGEW Data 28 decembrie 2014 08:41:42
Problema Barbar Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.8 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.y][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()
{
    if(!ok(1))
        return -1;
    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;
}