Cod sursa(job #2128786)

Utilizator DawlauAndrei Blahovici Dawlau Data 12 februarie 2018 04:39:14
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.73 kb
#include<fstream>
#include<deque>
#include<iostream>
using namespace std;
ifstream fin("barbar.in");
ofstream fout("barbar.out");
typedef pair<int, int> Pair;
const int NMAX = 1005;
const int moveX[] = {-1, 0, 1, 0}, moveY[] = {0, 1, 0, -1};

int auxiliarGrid[NMAX][NMAX], distanceToDragon[NMAX][NMAX], grid[NMAX][NMAX];
int rowsCount, columnsCount, xStart, yStart, xStop, yStop;

deque<Pair> Queue;

inline void read_data(){

    fin >> rowsCount >> columnsCount;

    int row, column;
    char c;
    for(row = 1; row <= rowsCount; ++row)
        for(column = 1; column <= columnsCount; ++column){

            fin >> c;
            if(c == '*')
                auxiliarGrid[row][column] = distanceToDragon[row][column] = -1;
            else if(c == 'I'){

                xStart = row;
                yStart = column;
            }
            else if(c == 'O'){

                xStop = row;
                yStop = column;
            }
            else if(c == 'D'){

                Queue.push_back({row, column});
                distanceToDragon[row][column] = 1;
            }
        }
}

inline void bord(){

    int row, column;
    for(row = 0; row <= rowsCount + 1; ++row)
        auxiliarGrid[row][0] = auxiliarGrid[row][columnsCount + 1] = distanceToDragon[row][0] = distanceToDragon[row][columnsCount + 1] = -1;

    for(column = 0; column <= columnsCount + 1; ++column)
        auxiliarGrid[0][column] = auxiliarGrid[rowsCount + 1][column] = distanceToDragon[0][column] = distanceToDragon[rowsCount + 1][column] = -1;
}

inline void getDistancesToDragons(){

    Pair currentCell, newCell;
    int direction;

    while(!Queue.empty()){

        currentCell = Queue.front();
        Queue.pop_front();

        for(direction = 0; direction < 4; ++direction){

            newCell = {currentCell.first + moveX[direction], currentCell.second + moveY[direction]};
            if(distanceToDragon[newCell.first][newCell.second] == 0){

                distanceToDragon[newCell.first][newCell.second] = distanceToDragon[currentCell.first][currentCell.second] + 1;
                Queue.push_back({newCell.first, newCell.second});
            }
        }
    }
}

inline void copyGrid(){

    int row, column;

    for(row = 0; row <= rowsCount + 1; ++row)
        for(column = 0; column <= columnsCount + 1; ++column)
            grid[row][column] = auxiliarGrid[row][column];
}

inline bool GoGoGo(int dist){

    copyGrid();

    Pair currentCell = {xStart, yStart};
    Pair newCell;

    if(distanceToDragon[xStart][yStart] - 1 >= dist){

        Queue.push_back(currentCell);
        grid[xStart][yStart] = 1;
    }

    int direction;

    while(!Queue.empty()){

        currentCell = Queue.front();
        Queue.pop_front();

        for(direction = 0; direction < 4; ++direction){

            newCell = {currentCell.first + moveX[direction], currentCell.second + moveY[direction]};
            if(grid[newCell.first][newCell.second] == 0 and distanceToDragon[newCell.first][newCell.second] - 1 >= dist){

                grid[newCell.first][newCell.second] = grid[currentCell.first][currentCell.second];
                Queue.push_back(newCell);
            }
        }
    }
    return grid[xStop][yStop];
}

inline int get_bestDistance(){

    int low = 1, high = rowsCount * columnsCount, bestDistance = -1, mid;

    while(low <= high){

        mid = (low + high) >> 1;
        if(GoGoGo(mid)){

            bestDistance = mid;
            low = mid + 1;
        }
        else
            high = mid - 1;
    }
    return bestDistance;
}

int main(){

    read_data();
    bord();
    getDistancesToDragons();
    fout << get_bestDistance();
}