Cod sursa(job #1275041)

Utilizator lokixdSebastian lokixd Data 24 noiembrie 2014 18:02:23
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.61 kb
#include <cstdio>
#include <queue>
#include <string>
#include <cstring>
 
#define Max_Size 1009
 
using namespace std;
 
const char iname[] = "barbar.in";
const char oname[] = "barbar.out";
 
typedef pair < int, int >   POINT;
 
int R, C, D[Max_Size][Max_Size];
bool Viz[Max_Size][Max_Size];
 
POINT In, Out;
 
queue < POINT > Q;
 
void Read()
{
    FILE *in = fopen(iname, "r");
    char my_String[Max_Size];
 
    fscanf(in, "%d%d", &R, &C);
 
    for(int i = 1; i <= R; ++i) {
        fscanf(in, "%s", my_String);
 
        for(int j = 0; j < C; ++j)  {
            if(my_String[j] == '.') continue;
 
            if(my_String[j] == 'I') {
                In = {i, j + 1};
                continue;
            }
 
            if(my_String[j] == 'O') {
                Out = {i, j + 1};
                continue;
            }
 
            if(my_String[j] == 'D') {
                Q.push( {i, j + 1} );
                Viz[i][j + 1] = 1;
                continue;
            }
 
            if(my_String[j] == '*') {
                D[i][j + 1] = -1;
                continue;
            }
        }
    }
}
 
short dl[] = {-1, 0, 0, 1};
short dc[] = {0, -1, 1, 0};
 
void Go_From_D()
{
    while(!Q.empty())   {
        POINT nod = Q.front();
        Q.pop();
 
        for(int i = 0; i < 4; ++i)  {
            int l = nod.first + dl[i], c = nod.second + dc[i];
 
            if(l > R || l < 1 || c > C || c < 1 || Viz[l][c] || D[l][c] == -1)   continue;
 
            D[l][c] = D[nod.first][nod.second] + 1;
            Viz[l][c] = 1;
            Q.push( {l, c} );
        }
    }
}
 
bool Can(int distance)
{
    if(D[In.first][In.second] < distance)   return 0;
 
    memset(Viz, 0, sizeof(Viz));
    while(!Q.empty())   Q.pop();
 
    Q.push(In), Viz[In.first][In.second]  = 1;
 
    while(!Q.empty())   {
        POINT nod = Q.front();
        Q.pop();
 
        for(int i = 0; i < 4; ++i)  {
            int l = dl[i] + nod.first, c = dc[i] + nod.second;
 
            if(l > R || l < 1 || c < 1 || c > C || Viz[l][c] || D[l][c] < distance)    continue;
 
            Viz[l][c] = 1;
            Q.push( {l, c} );
 
            if(l == Out.first && c == Out.second)   return 1;
        }
    }
 
    return 0;
}
 
int main()
{
    Read();
    Go_From_D();
 
    int st = 0, dr = R * C, mij, rez = -1;
    while(st <= dr) {
        mij = (st + dr) >> 1;
        if(Can(mij))    st = mij + 1, rez = mij;
        else            dr = mij - 1;
    }
 
    FILE *out = fopen(oname, "w");
 
    fprintf(out, "%d\n", rez);
 
    return 0;
}