Cod sursa(job #1818172)

Utilizator stefanmereutaStefan Mereuta stefanmereuta Data 28 noiembrie 2016 21:21:45
Problema Barbar Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.5 kb
#include <fstream>
#include <stdio.h>
#include <stdlib.h>

using namespace std;

void step(char **m, char **check, int R, int C, int x, int y, int newx, int newy);

void ver(char **m, char **check, int R, int C, int x, int y);

void directie(int x, int y, int &newx, int &newy, int dir);

void peretificare(char **marcat, int R, int C, int numar);

void reset(char **m, int R, int C) {
    for (int i = 0; i < R; i++) {
        for (int j = 0; j < C; j++) {
            m[i][j] = 0;
        }
    }
}

void freee(char **m, char **check, char ** marcat, int R) {
    for (int i = 0; i < R; i++) {
        free(m[i]);
        free(check[i]);
        free(marcat[i]);
    }

    free(m);
    free(check);
    free(marcat);
}

int main()
{
    ifstream fin("barbar.in");
    ofstream fout("barbar.out");

    int R, C, dist, i_start, j_start, i_iesire, j_iesire;
    char **m, **check, **marcat;

    fin >> R >> C;

    m = (char**) malloc(R * sizeof(char*));
    check = (char**) malloc(R * sizeof(char*));
    marcat = (char**) malloc(R * sizeof(char*));

    for (int i = 0; i < R; i++) {
        m[i] = (char*) malloc(C * sizeof(char));
        check[i] = (char*) malloc(C * sizeof(char));
        marcat[i] = (char*) malloc(C * sizeof(char));
    }

    reset(check, R, C);
    reset(marcat, R, C);

    for (int i = 0; i < R; i++) {
        for (int j = 0; j < C; j++) {
            fin >> m[i][j];

            if (m[i][j] == 'I') {
                i_start = i;
                j_start = j;

                m[i][j] = '.';
            } else if (m[i][j] == 'O') {
                i_iesire = i;
                j_iesire = j;

                m[i][j] = '.';
            } else if (m[i][j] == '*') {
                marcat[i][j] = 3;
            }
        }
    }

    check[i_start][j_start] = 1;

    ver(marcat, check, R, C, i_start, j_start);

    if (check[i_iesire][j_iesire] == 0) {
        fout << -1;

        freee(m, check, marcat, R);

        return 0;
    }

    for (int i = 0; i < R; i++) {
        for(int j = 0; j < C; j++) {
            if (m[i][j] == 'D') {
                marcat[i][j] = 1;
            }
        }
    }

    reset(check, R, C);

    ver(marcat, check, R, C, i_start, j_start);

    if (check[i_iesire][j_iesire] == 0) {
        fout << 0;

        freee(m, check, marcat, R);

        return 0;
    }

    for (dist = 1; dist < max(R, C); dist++) {
        peretificare(marcat, R, C, 2 - dist % 2);

        reset(check, R, C);

        if (marcat[i_start][j_start] == 0) {
            check[i_start][j_start] = 1;
        } else {
            break;
        }

        ver(marcat, check, R, C, i_start, j_start);

        if (check[i_iesire][j_iesire] != 1) {
            break;
        }
    }

    fout << dist;

    freee(m, check, marcat, R);

    fin.close();
    fout.close();
    return 0;
}

void step(char **marcat, char **check, int R, int C, int x, int y, int newx, int newy) {
    if (check[newx][newy] == 0) {
        if (marcat[newx][newy] != 0) {
            check[newx][newy] = 2;
        } else {
            check[newx][newy] = 1;
            ver(marcat, check, R, C, newx, newy);
        }
    }
}

void ver(char **marcat, char **check, int R, int C, int x, int y) {
    if (x <= R - 2) {
        step(marcat, check, R, C, x, y, x + 1, y);
    }

    if (y <= C - 2) {
        step(marcat, check, R, C, x, y, x, y + 1);
    }

    if (x >= 1) {
        step(marcat, check, R, C, x, y, x - 1, y);
    }

    if (y >= 1) {
        step(marcat, check, R, C, x, y, x, y - 1);
    }
}

void peretificare(char **marcat, int R, int C, int numar) {
    int newx, newy;

    for (int i = 0; i < R; i++) {
        for(int j = 0; j < C; j++) {
            if (marcat[i][j] == numar) {
                for(int dir = 0; dir <= 3; dir++) {
                    directie(i, j, newx, newy, dir);

                    if (newx >= 0 && newy >= 0 && newx <= R - 1 && newy <= C - 1 && marcat[newx][newy] == 0) {
                        marcat[newx][newy] = 3 - numar;
                    }
                }
            }
        }
    }
}

void directie(int x, int y, int &newx, int &newy, int dir) {
    if (dir == 0) {
        newx = x - 1;
        newy = y;
    } else if (dir == 1) {
        newx = x;
        newy = y + 1;
    } else if (dir == 2) {
        newx = x + 1;
        newy = y;
    } else if (dir == 3) {
        newx = x;
        newy = y - 1;
    }
}