Cod sursa(job #3138662)

Utilizator SarakottoBogudanSaracut Bogdan Andrei SarakottoBogudan Data 20 iunie 2023 21:17:53
Problema Barbar Scor 60
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.83 kb
#include <fstream>
#include <queue>
#include <string>

using namespace std;

ifstream cin("barbar.in");
ofstream cout("barbar.out");

int n, m;

int v[1001][1001];
int c[1001][1001];
int distanta[1001][1001];


int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

struct coord{
    int lin, col;
};

queue < coord > q;

coord st;
coord fin;
coord dragon;

string s;

bool inmat(coord cur)
{
    return cur.lin >= 1 && cur.lin <= n && cur.col >= 1 && cur.col <= m; 
}

void copiere()
{
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            c[i][j] = v[i][j];
        }
    }
}

int lee(coord st, coord fin)
{
    q.push(st);
    while(!q.empty())
    {
        coord cur = q.front();
        q.pop();
        coord vecin;
        for(int d = 0; d < 4; d++)
        {
            vecin.lin = cur.lin + dir[d][0];
            vecin.col = cur.col + dir[d][1];
            if(inmat(vecin) && c[vecin.lin][vecin.col] == 0)
            {
                c[vecin.lin][vecin.col] = c[cur.lin][cur.col] + 1;
                q.push(vecin);
            }
        }
    }
    return c[fin.lin][fin.col];
}

void lee_distanta(coord st, coord fin)
{
    distanta[st.lin][st.col] = 1;
    q.push(st);
    while(!q.empty())
    {
        coord cur = q.front();
        q.pop();
        coord vecin;
        for(int d = 0; d < 4; d++)
        {
            vecin.lin = cur.lin + dir[d][0];
            vecin.col = cur.col + dir[d][1];
            if(inmat(vecin) && distanta[vecin.lin][vecin.col] == 0)
            {
                distanta[vecin.lin][vecin.col] = distanta[cur.lin][cur.col] + 1;
                q.push(vecin);
            }
        }
    }
}

void lee2(coord st, int fin)
{
    q.push(st);
    while(!q.empty())
    {
        coord cur = q.front();
        q.pop();
        coord vecin;
        for(int d = 0; d < 4; d++)
        {
            vecin.lin = cur.lin + dir[d][0];
            vecin.col = cur.col + dir[d][1];
            if(inmat(vecin) && c[vecin.lin][vecin.col] == 0 && c[cur.lin][cur.col] > -2 - fin)
            {
                c[vecin.lin][vecin.col] = c[cur.lin][cur.col] - 1;
                q.push(vecin);
            }
        }
    }
}

int caut_binar(int stg, int dr)
{
    int ans = 0;

    c[st.lin][st.col] = 1;

    while(stg <= dr)
    {
        int mij = (stg + dr) / 2;
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= m; j++)
            {
                if(c[i][j] == -2)
                {
                    dragon.lin = i;
                    dragon.col = j;
                    lee2(dragon, mij);
                }
            }
        }

        int final = lee(st, fin);
        
        if(final > 0)
        {
            ans = mij;
            stg = mij + 1;
        }
        else if(final <= 0)
        {
            dr = mij - 1;
        }

        copiere();
    }

    if(ans >= 0)
    {
        return ans;
    }
    else 
    {
        return -2;
    }
}

int main()
{
    cin >> n >> m;
    getline(cin, s);
    for(int i = 1; i <= n; i++)
    {
        getline(cin, s);
        for(int j = 0; j < m; j++)
        {
            if(s[j] == 'I')
            {
                st.lin = i;
                st.col = j + 1;
            }
            else if(s[j] == 'D')
            {
                v[i][j + 1] = -2;
            }
            else if(s[j] == '*')
            {
                v[i][j + 1] = -1;
            }
            else if(s[j] == 'O')
            {
                fin.lin = i;
                fin.col = j + 1;
            }
        }
        s.clear();
    }
    copiere();

    int dist_min = 1e7;

    lee_distanta(st, fin);

    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            if(c[i][j] == -2 && distanta[i][j] < dist_min)
            {
                dist_min = distanta[i][j] - 1;
            }
        }
    }

    int ans = caut_binar(0, dist_min) + 1;
    
    cout << ans << '\n';

    /*
    cout << st.lin << " " << st.col << '\n';
    cout << fin.lin << " " << fin.col << '\n';

    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            cout << c[i][j] << " ";
        }
        cout << '\n';
    }

    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            if(c[i][j] == -2)
            {
                dragon.lin = i;
                dragon.col = j;
                lee2(dragon, 3);
            }
        }
    }

    lee(st, fin);

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


    return 0;
}