Cod sursa(job #2810371)

Utilizator chiriacandrei25Chiriac Andrei chiriacandrei25 Data 29 noiembrie 2021 12:27:12
Problema Barbar Scor 10
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.86 kb
#include <fstream>
#include <cstring>
using namespace std;
ifstream cin("barbar.in");
ofstream cout("barbar.out");
const int NMAX = 1005;
int n, m, dist[NMAX][NMAX];
int t[NMAX][NMAX];
char a[NMAX][NMAX], b[NMAX][NMAX];

struct Celula
{
    int l, c;
};
Celula start, fin;

bool isValid(Celula cell, int minDist = -1)
{
    if (minDist == -1 and (cell.l >= 1 and cell.l <= n and cell.c >= 1 and cell.c <= m and !strchr("D*", b[cell.l][cell.c])))
        return true;

    if (minDist != -1 and (cell.l >= 1 and cell.l <= n and cell.c >= 1 and cell.c <= m and !strchr("D*", b[cell.l][cell.c])) and dist[cell.l][cell.c] >= minDist)
        return true;

    return false;
}

void Lee(Celula Q[], int top, int minDist = -1)
{
    const int dx[] = {-1, 0, 1, 0};
    const int dy[] = {0, 1, 0, -1};
    int bottom = 1;
    while (top >= bottom)
    {
        Celula cell = Q[bottom++];

        for (int dir = 0; dir < 4; dir++)
        {
            Celula neighbour = {cell.l + dx[dir], cell.c + dy[dir]};

            if (minDist == -1 and isValid(neighbour))
            {
                Q[++top] = neighbour;
                dist[neighbour.l][neighbour.c] = dist[cell.l][cell.c] + 1;
                b[cell.l][cell.c] = '*';
            }
            else if (minDist != -1 and isValid(neighbour, minDist))
            {
                Q[++top] = neighbour;
                t[neighbour.l][neighbour.c] = t[cell.l][cell.c] + 1;
                b[cell.l][cell.c] = '*';
            }
        }
    }
}

void traictorie(int mini, int &sol)
{
    for (int i = 1; i <= n; i++)
        memset(t[i], 0, sizeof(t[i]));

    Celula q[1005];
    int k = 0;
    while (++k < 1005 and q[k].l != 0 and q[k].c != 0)
        q[k] = {0, 0};

    q[1] = start;
    Lee(q, 1, mini);
    
    sol = t[fin.l][fin.c];
    
    if(sol >= mini);
    
    else sol = -1;
}

int main()
{
    cin >> n >> m;

    Celula q[1000 * 1000 + 5];
    int k = 0;

    while (++k < 1000 * 1000 + 5 and q[k].l != 0 and q[k].c != 0)
        q[k] = {0, 0};

    for (int i = 1; i <= n; i++)
    {
        cin >> (a[i] + 1);
        for (int j = 1; j <= m; j++)
        {
            b[i][j] = a[i][j];
            if (a[i][j] == 'D')
                q[++k] = {i, j};

            else if (a[i][j] == 'I')
                start = {i, j};
            else if (a[i][j] == 'O')
                fin = {i, j};
        }
    }

    Lee(q, k);

    int l = 1, r = n * m, mid, sol = -1;
    while (l <= r)
    {
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++)
                b[i][j] = a[i][j];

        mid = (l + r) / 2;
        int l = 0;
        traictorie(mid, l);

        if (l != -1)
            sol = l, l = mid + 1;
        else
            r = mid - 1;
    }

    cout << sol << '\n';

    return 0;
}