Cod sursa(job #2338918)

Utilizator ReeeBontea Mihai Reee Data 7 februarie 2019 23:21:15
Problema Barbar Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.41 kb
#include <fstream>
#include <queue>
#include <cstring>
#define NMAX 1001

using namespace std;

ofstream fout("barbar.out");

int R , C , Sol[NMAX][NMAX], PD[NMAX][NMAX]; // dimensiunile temnitei, matricea pt calcularea iesirii si matricea pentru proximitatea dragonilor
short startx , starty , stopx ,stopy , solutia = -1; // coordonatele de pornire si de sosire , si solutia , initializata cu -1

short di[4] = {0 , 0 , 1 , -1}; // vector de deplasare pe linii
short dj[4] = {1 , -1 , 0 , 0}; // vector de deplasare pe coloane

queue < pair < short , short > > coada;

void Citire()
{
    char c;
    ifstream fin("barbar.in");
    fin >> R >> C;
    for ( short i = 1 ; i <= R ; ++i )
        for ( short j = 1 ; j <= C ; ++j )
            {
                fin >> c;
                if ( c == 'D') // Dragoni
                    {
                        PD[i][j] = 1;
                        coada.push( make_pair( i , j ) );
                    }
                else if ( c == '*' ) // Perete
                    PD[i][j] = -1;
                else if ( c == 'I' ) // Retinem coordonatele de pornire
                {
                    startx = i;
                    starty = j;
                }
                else if ( c == 'O' ) // Retinem coordonatele de sosire
                {
                    stopx = i;
                    stopy = j;
                }
            }
}

bool OK( short i , short j )
{
    if ( i < 1 || j < 1 || i > R || j > C )
        return false;
    if ( PD[i][j] != 0 )
        return false;
    return true;
}

bool OK1 ( short i , short j , short k )
{
    if ( i < 1 || j < 1 || i > R || j > C )
        return false;
    if ( Sol[i][j] != 0 )
        return false;
    if ( PD[i][j] <= k && PD[i][j] != 0 )
        return false;
    return true;
}

void ProximitateaDragonilor()
{
    int i , j , i_urmator , j_urmator;
    while ( !coada.empty() )
    {
        i = coada.front().first;
        j = coada.front().second;
        coada.pop();
        for ( short directie = 0 ; directie < 4 ; ++directie )
        {
            i_urmator = i + di[directie];
            j_urmator = j + dj[directie];
            if ( OK( i_urmator , j_urmator ) )
            {
                PD[i_urmator][j_urmator] = PD[i][j] + 1;
                coada.push( make_pair( i_urmator , j_urmator ) );
            }
        }
    }
}

void GasireaSolutie( int k ) // parametrul k reprezinta distanta pana la dragon admisa
{
    memset( Sol , 0 , NMAX * NMAX );

    int i , j , i_urmator , j_urmator;
    Sol[startx][starty] = 1;
    coada.push( make_pair( startx , starty ) );
    while ( !coada.empty() )
    {
        i = coada.front().first;
        j = coada.front().second;
        coada.pop();
        for ( short directie = 0 ; directie < 4 ; ++directie )
        {
            i_urmator = i + di[directie];
            j_urmator = j + dj[directie];
            if ( OK1( i_urmator , j_urmator , k ) )
            {
                Sol[i_urmator][j_urmator] = Sol[i][j] + 1;
                coada.push( make_pair( i_urmator , j_urmator ) );
            }
        }
    }
    if ( Sol[stopx][stopy] )
    {
        solutia = k;
        GasireaSolutie( k + 1 );
    }
}

int main()
{
    Citire();
    ProximitateaDragonilor(); // am format matricea PD[NMAX][NMAX]
    GasireaSolutie( 1 );
    fout << solutia;
    return 0;
}