Cod sursa(job #2288095)

Utilizator mihaicivMihai Vlad mihaiciv Data 22 noiembrie 2018 20:51:53
Problema Barbar Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.52 kb
#include <iostream>
#include <fstream>

using namespace std;


void createMap(int, int[], int[], int, int, int[], int[], char**, int**);
void searchMin(int&, int, int, char**, int**, int, int, int, int, int, int);
int canCreatePath(int, int, char**, int**, int, int, int, int, int);

int main() {

    ifstream f("barbar.in");
    ofstream g("barbar.out");

    int n, m;
    f >> n >> m;
    char **a = new char*[n];
    int **b = new int*[n];
    for (int i = 0; i < n; ++i) {
        b[i] = new int[m];
        a[i] = new char[m];

    }
    int dragonNumber = 0;
    int dragonX[n * m];
    int dragonY[n * m];
    int stx, sty, finx, finy;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            b[i][j] = 0;
            f >> a[i][j];
            if (a[i][j] == 'D') {
                dragonX[dragonNumber] = i;
                dragonY[dragonNumber] = j;
                dragonNumber ++;
            } else if (a[i][j] == 'I') {
                stx = i;
                sty = j;
            } else if (a[i][j] == 'O') {
                finx = i;
                finy = j;
            }
        }
    }
    int dx[] = {1, -1, 0, 0};
    int dy[] = {0, 0, 1, -1};
    createMap(dragonNumber, dragonX, dragonY, n, m, dx, dy, a, b);

    /*
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cout << b[i][j] << " ";
        }
        cout << "\n";
    }*/


    int minimDistance = n * m + 2;

    searchMin(minimDistance, n, m, a, b, 0, n * m, stx, sty, finx, finy);
    if (minimDistance == n * m + 2) {
        g << -1;
    } else {g << minimDistance - 1;}


    return 0;
}

void createMap(int dragonNumber, int dragonX[], int dragonY[], int n, int m, int dx[], int dy[], char **a, int**b) {
    int coadaX[n * m];
    int coadaY[n * m];
    int st = 0;
    int fin = 0;
    for (int i = 0; i < dragonNumber; ++i) {
        coadaX[i] = dragonX[i];
        coadaY[i] = dragonY[i];
        b[coadaX[i]][coadaY[i]] = 1;
        fin ++;
    }

    fin --;

    while (st <= fin) {
        int currentX = coadaX[st];
        int currentY = coadaY[st];
        st ++;
        for (int j = 0; j < 4; ++j) {
            int xAux = currentX + dx[j];
            int yAux = currentY + dy[j];
            if ( 0 <= xAux && xAux < n && 0 <= yAux && yAux < m && a[xAux][yAux] != '*' && b[xAux][yAux] == 0 ) {
                fin ++;
                b[xAux][yAux] = b[currentX][currentY] + 1;
                coadaX[fin] = xAux;
                coadaY[fin] = yAux;
            }
        }
    }

}
void searchMin(int &minimDistance, int n, int m, char **a, int **b, int st, int dr, int stx, int sty, int finx, int finy) {

    if (st <= dr) {
        if ( st == dr ) {
            if (canCreatePath(n, m, a, b, st, stx, sty, finx, finy) == 1) {
                if (minimDistance == n * m + 2) {
                    minimDistance = st;
                } else {
                    minimDistance = max(st, minimDistance);
                }
            }
        } else {
            int mij = (st + dr) / 2;
            if ( canCreatePath(n, m, a, b, mij, stx, sty, finx, finy) == 1 ) {
                minimDistance = mij;
                searchMin(minimDistance, n, m, a, b, mij + 1, dr, stx, sty, finx, finy);
            } else {
                searchMin(minimDistance, n, m, a, b, st, mij, stx, sty, finx, finy);
            }
        }
    }
}

int canCreatePath(int n, int m, char **a, int **b, int dist, int stx, int sty, int finx, int finy) {

    int st = 0;
    int fin = 0;
    int coadaX[n * m], coadaY[n * m];
    coadaX[st] = stx;
    coadaY[st] = sty;
    bool canContinue = true;
    int vis[n][m];
    int dx[] = {1, -1, 0, 0};
    int dy[] = {0, 0, 1, -1};

    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            vis[i][j] = 0;
        }
    }

    vis[stx][sty] = 1;

    while (st <= fin && vis[finx][finy] == 0) {
        int currentX = coadaX[st];
        int currentY = coadaY[st];
        st ++;
        for (int i = 0; i < 4; ++i) {
            int xAux = currentX + dx[i];
            int yAux = currentY + dy[i];
            if (0 <= xAux && xAux < n && 0 <= yAux && yAux < m && a[xAux][yAux] != '*' && vis[xAux][yAux] == 0 && b[xAux][yAux] >= dist) {
                fin ++;
                vis[xAux][yAux] = 1;
                coadaX[fin] = xAux;
                coadaY[fin] = yAux;
            }
        }
    }

    return (vis[finx][finy] != 0);

}