Cod sursa(job #2830648)

Utilizator thor13thor13 thor13 Data 10 ianuarie 2022 08:54:47
Problema Barbar Scor 100
Compilator c-64 Status done
Runda Arhiva de probleme Marime 3.44 kb
#include <stdio.h>
#include <string.h>

#define nmax 1002
#define NIL -1
#define coada_size 1000000

int v[nmax][nmax];
char drum[nmax][nmax];
int coada[coada_size][2];
int poz_coada;
char dlin[4] = {-1, 0, 1, 0};
char dcol[4] = {0, 1, 0, -1};
int n, m, lstart, cstart, lstop, cstop;

int mini(int a, int b) {
    return ((a <= b) ? a : b);
}

void bordare() {
    int i;
    for (i = 0; i <= n + 1; i++)
        v[i][0] = v[i][m + 1] = NIL;
    for (i = 0; i <= m + 1; i++)
        v[0][i] = v[n + 1][i] = NIL;
}

void lee() {
    int poz_start, i;
    poz_start = 0;
    while (poz_start != poz_coada) {
        for (i = 0; i < 4; i++) {
            if (v[coada[poz_start][0] + dlin[i]][coada[poz_start][1] + dcol[i]] ==
                0) {///daca elementul nu a fost adaugat in coada
                v[coada[poz_start][0] + dlin[i]][coada[poz_start][1] + dcol[i]] =
                        v[coada[poz_start][0]][coada[poz_start][1]] + 1;
                coada[poz_coada][0] = coada[poz_start][0] + dlin[i];
                coada[poz_coada][1] = coada[poz_start][1] + dcol[i];
                poz_coada++;
            }
        }
        poz_start++;
    }
}

void initializare() {
    int i;
    for (i = 0; i <= n + 1; i++)
        memset(drum[i], 0, sizeof(drum[i]));
}

int caut_drum(int val_max) {
    initializare();
    int poz_start, i, ans;
    poz_start = 0;
    coada[poz_start][0] = lstart;
    coada[poz_start][1] = cstart;
    drum[lstart][cstart] = 1;
    ans = 0;
    poz_coada = 1;
    while (poz_start != poz_coada && ans == 0) {
        for (i = 0; i < 4; i++) {
            if (drum[coada[poz_start][0] + dlin[i]][coada[poz_start][1] + dcol[i]] == 0 &&
                (v[coada[poz_start][0] + dlin[i]][coada[poz_start][1] + dcol[i]] - 1) >= val_max) {
                drum[coada[poz_start][0] + dlin[i]][coada[poz_start][1] + dcol[i]] = 1;
                coada[poz_coada][0] = coada[poz_start][0] + dlin[i];
                coada[poz_coada][1] = coada[poz_start][1] + dcol[i];
                if (coada[poz_coada][0] == lstop && coada[poz_coada][1] == cstop)
                    ans = 1;
                poz_coada++;
            }
        }
        poz_start++;
    }
    return ans;
}

int cautbin(int start, int stop) {
    int pivot;
    while (stop - start > 1) {
        pivot = (start + stop) >> 1;
        if (caut_drum(pivot) == 1)
            start = pivot;
        else
            stop = pivot;
    }
    return start == 0 ? NIL : start;
}

int main() {
    int i, j;
    char ch;
    FILE *fin, *fout;
    fin = fopen("barbar.in", "r");
    fscanf(fin, "%d%d\n", &n, &m);
    for (i = 1; i <= n; i++) {
        for (j = 1; j <= m; j++) {
            ch = fgetc(fin);
            if (ch == '*')
                v[i][j] = NIL;
            else if (ch == 'D') {///adaugam dragonul in coada
                coada[poz_coada][0] = i;
                coada[poz_coada][1] = j;
                poz_coada++;
                v[i][j] = 1;
            } else if (ch == 'I') {
                lstart = i;
                cstart = j;
            } else if (ch == 'O') {
                lstop = i;
                cstop = j;
            }
        }
        fgetc(fin);
    }
    fclose(fin);
    bordare(n, m);
    ///alcatuim matricea cu dist minim de la un pct la un dragon
    lee();
    ///cautam binar valoarea minima pt care ajunge la rezultat
    fout = fopen("barbar.out", "w");
    fprintf(fout, "%d\n", cautbin(0, mini(v[lstart][cstart], v[lstop][cstop])));
    fclose(fout);
    return 0;
}